+
+
+#define BAUDRATE 115200
+
+#define USART_DEVICE USART1
+
+#define USART_TX_GPIO_CLK RCC_AHBPeriph_GPIOD
+#define USART_TX_PORT GPIOD
+#define USART_TX_PIN 1
+#define USART_TX_PINSRC GPIO_PinSource1
+
+#define USART_RX_GPIO_CLK RCC_AHBPeriph_GPIOB
+#define USART_RX_PORT GPIOB
+#define USART_RX_PIN 4
+#define USART_RX_PINSRC GPIO_PinSource4
+
+
+
+// inefficient, but we have time and space
+#define RX_BUF_LEN 1040
+uint8_t rxbuf[RX_BUF_LEN];
+uint16_t rxptr = 0;
+uint16_t rxlen = 0;
+
+
+
+/**
+ * @brief Initializes USART peripheral at fixed baud rate.
+ */
+void comm_init()
+{
+ // USART_InitTypeDef usart;
+ // NVIC_InitTypeDef nvic;
+
+ // enable GPIO clock
+ RCC_AHBPeriphClockCmd(USART_TX_GPIO_CLK | USART_RX_GPIO_CLK, ENABLE);
+
+ // configure USART GPIO
+ GPIO_PinAFConfig(USART_TX_PORT, USART_TX_PINSRC, GPIO_AF_1);
+ GPIO_PinAFConfig(USART_RX_PORT, USART_RX_PINSRC, GPIO_AF_1);
+
+ USART_RX_PORT->MODER &= ~(GPIO_MODER_MODER0 << 2 * USART_RX_PIN);
+ USART_RX_PORT->MODER |= (GPIO_Mode_AF << 2 * USART_RX_PIN); // alt function
+
+ USART_TX_PORT->MODER &= ~(GPIO_MODER_MODER0 << 2 * USART_TX_PIN);
+ USART_TX_PORT->OTYPER &= ~(GPIO_OTYPER_OT_0 << USART_TX_PIN); // push pull
+ USART_TX_PORT->OSPEEDR &= ~(GPIO_OSPEEDR_OSPEEDR0 << 2 * USART_TX_PIN); // slow
+ USART_TX_PORT->MODER |= (GPIO_Mode_AF << 2 * USART_TX_PIN); // alt function
+
+ // configure NVIC
+ /*
+ nvic.NVIC_IRQChannel = USART1_IRQn;
+ nvic.NVIC_IRQChannelPriority = 1;
+ nvic.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&nvic);
+ */
+
+ // enable USART clock
+ RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
+
+ /*
+ // configure USART peripheral
+ usart.USART_BaudRate = BAUDRATE;
+ usart.USART_WordLength = USART_WordLength_8b;
+ usart.USART_StopBits = USART_StopBits_1;
+ usart.USART_Parity = USART_Parity_No;
+ usart.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
+ usart.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
+ USART_Init(USART1, &usart);
+ */
+
+ // configure USART peripheral manually
+ // we do this as the library uses division which bloats flash space
+ USART1->CR1 = 0; // disable USART
+ USART1->CR1 = USART_Mode_Rx | USART_Mode_Tx; // 8 bits, no parity, tx/rx enabled
+ USART1->CR2 = 0; // 1 stop bit
+ USART1->CR3 = 0;
+ USART1->BRR = 0x45; // 115200 baud rate @8MHz (per datasheet)
+
+ // enable USART interrupts
+ // USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
+
+ // enable USART
+ USART1->CR1 |= USART_CR1_UE;
+}
+
+/**
+ * @brief Receives data from USART.
+ * @param *data: Array to save the received data.
+ * @param length: Size of the data.
+ * @return status: Report about the success of the receiving.
+ */
+BL_comm_status comm_rx(uint8_t *data, uint16_t length)
+{
+ uint16_t i;
+ uint16_t timeout;
+
+ /*
+ // wait for more data to arrive
+ timeout = COMM_TIMEOUT;
+ while (rxlen < length) {
+ timeout--;
+ if (!timeout) return COMM_RX_TIMEOUT;
+ }
+
+ // copy data to final buffer
+ for (i = 0; i < length; i++) {
+ data[i] = rxbuf[rxptr++];
+ if (rxptr >= RX_BUF_LEN) rxptr = 0;
+ rxlen--;
+ }
+ */
+
+ for (i = 0; i < length; i++) {
+ timeout = 0xffff;
+ while (!(USART1->ISR & USART_ISR_RXNE_Msk) && timeout) {
+ timeout--;
+ }
+
+ if (timeout) {
+ // there is new data waiting for us
+ data[i] = USART1->RDR;
+ } else {
+ // there is no data returned in time
+ return COMM_ERROR;
+ }
+ }
+
+ return COMM_OK;
+}
+
+/**
+ * @brief Transmits a single char to UART.
+ * @param *data: The char.
+ * @return status: Report about the success of the transmission.
+ */
+BL_comm_status comm_tx_byte(uint8_t data)
+{
+ USART_SendData(USART1, data);
+
+ while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
+
+ return COMM_OK;
+}
+
+/**
+ * @brief Transmits a null-terminated string over USART.
+ * @param *data: String array.
+ * @return status: Report about the success of the transmission.
+ */
+BL_comm_status comm_tx_str(uint8_t *data)
+{
+ uint8_t i;
+ uint16_t len = 0;
+
+ len = strlen((const char *)data);
+
+ for(i = 0; i < len; i++) {
+ comm_tx_byte(data[i]);
+ }
+
+ while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
+
+ return COMM_OK;
+}
+
+/*
+void USART1_IRQHandler()
+{
+ uint8_t data;
+
+ if (USART1->ISR & USART_ISR_RXNE_Msk) {
+ // read data
+ data = USART1->RDR;
+
+ // only add data if there is room
+ if (rxlen >= RX_BUF_LEN) return;
+ rxlen++;
+
+ // next position
+ if (++rxptr >= RX_BUF_LEN) rxptr = 0;
+
+ // save data
+ rxbuf[rxptr] = data;
+ }
+}
+*/
diff --git a/bootloader_hk32f030m_uart_xmodem/code/src/user_io.c b/bootloader_hk32f030m_uart_xmodem/code/src/user_io.c
new file mode 100644
index 0000000..c144808
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/code/src/user_io.c
@@ -0,0 +1,56 @@
+/*
+ * user_io.c
+ *
+ * Created on: Jun 23, 2023
+ * Author: true
+ */
+
+
+#include "hk32f030m.h"
+#include "user_io.h"
+
+
+
+void user_io_init()
+{
+ // enable gpio clocks
+ RCC_AHBPeriphClockCmd(BTN_CLK | LED_CLK, ENABLE);
+
+ // configure led
+#if LED_ACT_DIR == 0
+ LED_PORT->BSRR = (1 << LED_PIN); // idle high
+#else
+ LED_PORT->BRR = (1 << LED_PIN); // idle low
+#endif
+ LED_PORT->OTYPER &= ~(GPIO_OTYPER_OT_0 << LED_PIN); // push pull
+ LED_PORT->OSPEEDR &= ~(GPIO_OSPEEDR_OSPEEDR0 << 2 * LED_PIN); // slow
+ LED_PORT->MODER &= ~(GPIO_MODER_MODER0 << 2 * LED_PIN);
+ LED_PORT->MODER |= (GPIO_Mode_OUT << 2 * LED_PIN); // output
+
+ // configure button
+ BTN_PORT->MODER &= ~(GPIO_MODER_MODER0 << 2 * BTN_PIN); // input
+ BTN_PORT->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << 2 * BTN_PIN);
+#if BTN_ACT_DIR == 0
+ BTN_PORT->PUPDR |= (GPIO_PuPd_UP << 2 * BTN_PIN); // pulled high
+#else
+ BTN_PORT->PUPDR |= (GPIO_PuPd_DOWN << 2 * BTN_PIN); // pulled low
+#endif
+}
+
+void user_led_init()
+{
+ // led blinking timer; set LED flash rate here
+ SysTick_Config(8000000 / 20);
+}
+
+void user_led_set(uint8_t lit)
+{
+#if LED_ACT_DIR == 0
+ if (lit) LED_PORT->BRR = (1 << LED_PIN);
+ else LED_PORT->BSRR = (1 << LED_PIN);
+#else
+ if (lit) LED_PORT->BSRR = (1 << LED_PIN);
+ else LED_PORT->BRR = (1 << LED_PIN);
+#endif
+}
+
diff --git a/bootloader_hk32f030m_uart_xmodem/code/src/xmodem.c b/bootloader_hk32f030m_uart_xmodem/code/src/xmodem.c
new file mode 100644
index 0000000..b1af977
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/code/src/xmodem.c
@@ -0,0 +1,267 @@
+/*
+ * xmodem.c
+ *
+ * Created on: Jun 23, 2023
+ * Author: true
+ *
+ * originally Copyright (c) 2018 Ferenc Nemeth - https://github.com/ferenc-nemeth - 21 Dec 2018
+ * modified for use with HK32F and my coding style.
+ *
+ * under MIT license.
+ */
+
+#include "xmodem.h"
+#include "flash.h"
+#include "usart.h"
+
+
+
+/* Global variables. */
+static uint8_t xmodem_packet_number = 1u; /**< Packet number counter. */
+static uint32_t xmodem_flash_w_addr = 0u; /**< Address where we have to write. */
+static uint8_t x_first_packet_rcvd = 0; /**< First packet or not. */
+
+/* Local functions. */
+static uint16_t xmodem_calc_crc(uint8_t *data, uint16_t length);
+static BL_xmodem_status xmodem_handle_packet(uint8_t size);
+static BL_xmodem_status xmodem_error_handler(uint8_t *error_number, uint8_t max_error_number);
+
+
+
+/**
+ * @brief This function is the base of the Xmodem protocol.
+ * When we receive a header from UART, it decides what action it shall take.
+ * @param void
+ * @return void
+ */
+void xmodem_receive(void)
+{
+ volatile BL_xmodem_status status = X_OK;
+ uint8_t error_number = 0u;
+
+ x_first_packet_rcvd = 0;
+ xmodem_packet_number = 1u;
+ xmodem_flash_w_addr = USER_APP_START_ADDR;
+
+ /* Loop until there isn't any error (or until we jump to the user application). */
+ while (status == X_OK) {
+ uint8_t header = 0x00u;
+
+ /* Get the header from UART. */
+ BL_comm_status status_c = comm_rx(&header, 1);
+
+ /* Spam the host (until we receive something) with ACSII "C", to notify it, we want to use CRC-16. */
+ if ((status_c != COMM_OK) && (x_first_packet_rcvd == false)) {
+ comm_tx_byte(X_C);
+ }
+
+ /* Uart timeout or any other errors. */
+ else if ((status_c != COMM_OK) && (x_first_packet_rcvd)) {
+ status = xmodem_error_handler(&error_number, X_MAX_ERRORS);
+ }
+
+ /* Do nothing. */
+ else {
+
+ }
+
+ /* The header can be: SOH, STX, EOT and CAN. */
+ BL_xmodem_status packet_status = X_ERROR;
+
+ switch(header) {
+ /* 128 or 1024 bytes of data. */
+ case X_SOH:
+ case X_STX: {
+ /* If the handling was successful, then send an ACK. */
+ packet_status = xmodem_handle_packet(header);
+ if (packet_status == X_OK) {
+ comm_tx_byte(X_ACK);
+ }
+
+ /* If the error was flash related, then immediately set the error counter to max (graceful abort). */
+ else if (packet_status == X_ERROR_FLASH) {
+ error_number = X_MAX_ERRORS;
+ status = xmodem_error_handler(&error_number, X_MAX_ERRORS);
+ }
+
+ /* Error while processing the packet, either send a NAK or do graceful abort. */
+ else {
+ status = xmodem_error_handler(&error_number, X_MAX_ERRORS);
+ }
+
+ break;
+ }
+
+ /* End of Transmission. */
+ case X_EOT: {
+ /* ACK, feedback to user (as a text), then jump to user application. */
+ comm_tx_byte(X_ACK);
+ comm_tx_str((uint8_t*)"\r\nfirmware updated.\r\nstarting firmware.\r\n\r\n");
+ jump_to_user_app();
+ break;
+ }
+
+ /* Abort from host. */
+ case X_CAN: {
+ status = X_ERROR;
+ break;
+ }
+
+ /* Wrong header. */
+ default: {
+ if (status_c == COMM_OK) {
+ status = xmodem_error_handler(&error_number, X_MAX_ERRORS);
+ }
+ break;
+ }
+ }
+ }
+}
+
+/**
+ * @brief Calculates the CRC-16 for the input package.
+ * @param *data: Array of the data which we want to calculate.
+ * @param length: Size of the data, either 128 or 1024 bytes.
+ * @return status: The calculated CRC.
+ */
+static uint16_t xmodem_calc_crc(uint8_t *data, uint16_t length)
+{
+ uint16_t crc = 0u;
+ while (length)
+ {
+ length--;
+ crc = crc ^ ((uint16_t)*data++ << 8u);
+ for (uint8_t i = 0u; i < 8u; i++)
+ {
+ if (crc & 0x8000u)
+ {
+ crc = (crc << 1u) ^ 0x1021u;
+ }
+ else
+ {
+ crc = crc << 1u;
+ }
+ }
+ }
+ return crc;
+}
+
+/**
+ * @brief This function handles the data packet we get from the xmodem protocol.
+ * @param header: SOH or STX.
+ * @return status: Report about the packet.
+ */
+static BL_xmodem_status xmodem_handle_packet(uint8_t header)
+{
+ BL_xmodem_status status = X_OK;
+ uint16_t size = 0u;
+
+ /* 2 bytes for packet number, 1024 for data, 2 for CRC*/
+ uint8_t rcvd_packet_number[X_PACKET_NUMBER_SIZE];
+ uint8_t rcvd_packet_data[X_PACKET_1024_SIZE];
+ uint8_t rcvd_packet_crc[X_PACKET_CRC_SIZE];
+
+ /* Get the size of the data. */
+ if (header == X_SOH) {
+ size = X_PACKET_128_SIZE;
+ } else if (header == X_STX) {
+ size = X_PACKET_1024_SIZE;
+ } else {
+ /* Wrong header type. This shoudn't be possible... */
+ status |= X_ERROR;
+ }
+
+ BL_comm_status status_c = COMM_OK;
+
+ /* Get the packet number, data and CRC from UART. */
+ status_c |= comm_rx(&rcvd_packet_number[0u], X_PACKET_NUMBER_SIZE);
+ status_c |= comm_rx(&rcvd_packet_data[0u], size);
+ status_c |= comm_rx(&rcvd_packet_crc[0u], X_PACKET_CRC_SIZE);
+
+ /* Merge the two bytes of CRC. */
+ uint16_t crc_rcvd = ((uint16_t)rcvd_packet_crc[X_PACKET_CRC_HIGH_INDEX] << 8u)
+ | ((uint16_t)rcvd_packet_crc[X_PACKET_CRC_LOW_INDEX]);
+
+ /* We calculate it too. */
+ uint16_t crc_calc = xmodem_calc_crc(&rcvd_packet_data[0u], size);
+
+ /* Communication error. */
+ if (status_c != COMM_OK) {
+ status |= X_ERROR_UART;
+ }
+
+ /* If it is the first packet, then erase the memory. */
+ if ((status == X_OK) && (x_first_packet_rcvd == false)) {
+ if (flash_erase_user_app() == FLASH_OK) {
+ x_first_packet_rcvd = true;
+ } else {
+ status |= X_ERROR_FLASH;
+ }
+ }
+
+ /* Error handling and flashing. */
+ if (status == X_OK) {
+ if (xmodem_packet_number != rcvd_packet_number[0u]) {
+ /* Packet number counter mismatch. */
+ status |= X_ERROR_NUMBER;
+ }
+
+ if ((rcvd_packet_number[X_PACKET_NUMBER_INDEX] + rcvd_packet_number[X_PACKET_NUMBER_COMPLEMENT_INDEX]) != 255) {
+ /* The sum of the packet number and packet number complement aren't 255. */
+ /* The sum always has to be 255. */
+ status |= X_ERROR_NUMBER;
+ }
+
+ if (crc_calc != crc_rcvd) {
+ /* The calculated and received CRC are different. */
+ status |= X_ERROR_CRC;
+ }
+ }
+
+ /* Do the actual flashing if there weren't any errors. */
+ if ((status == X_OK) &&
+ (flash_write(xmodem_flash_w_addr, rcvd_packet_data, size)) != FLASH_OK) {
+
+ /* Flashing error. */
+ status |= X_ERROR_FLASH;
+ }
+
+ /* Raise the packet number and the address counters (if there weren't any errors). */
+ if (status == X_OK) {
+ xmodem_packet_number++;
+ xmodem_flash_w_addr += size;
+ }
+
+ return status;
+}
+
+/**
+ * @brief Handles the xmodem error.
+ * Raises the error counter, then if the number of the errors reached critical, do a graceful abort, otherwise send a NAK.
+ * @param *error_number: Number of current errors (passed as a pointer).
+ * @param max_error_number: Maximal allowed number of errors.
+ * @return status: X_ERROR in case of too many errors, X_OK otherwise.
+ */
+static BL_xmodem_status xmodem_error_handler(uint8_t *error_number, uint8_t max_error_number)
+{
+ BL_xmodem_status status = X_OK;
+
+ /* Raise the error counter. */
+ (*error_number)++;
+
+ /* If the counter reached the max value, then abort. */
+ if ((*error_number) >= max_error_number) {
+ /* Graceful abort. */
+ comm_tx_byte(X_CAN);
+ comm_tx_byte(X_CAN);
+ status = X_ERROR;
+ }
+
+ /* Otherwise send a NAK for a repeat. */
+ else {
+ comm_tx_byte(X_NAK);
+ status = X_OK;
+ }
+
+ return status;
+}
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/CM0/Core/arm_common_tables.h b/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/CM0/Core/arm_common_tables.h
new file mode 100644
index 0000000..8742a56
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/CM0/Core/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/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/CM0/Core/arm_const_structs.h b/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/CM0/Core/arm_const_structs.h
new file mode 100644
index 0000000..726d06e
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/CM0/Core/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/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/CM0/Core/arm_math.h b/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/CM0/Core/arm_math.h
new file mode 100644
index 0000000..d33f8a9
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/CM0/Core/arm_math.h
@@ -0,0 +1,7154 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+*
+* $Date: 20. October 2015
+* $Revision: V1.4.5 b
+*
+* Project: CMSIS DSP Library
+* Title: arm_math.h
+*
+* Description: Public header file for CMSIS DSP Library
+*
+* Target Processor: Cortex-M7/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.
+ * -------------------------------------------------------------------- */
+
+/**
+ \mainpage CMSIS DSP Software Library
+ *
+ * Introduction
+ * ------------
+ *
+ * This user manual describes the CMSIS DSP software library,
+ * a suite of common signal processing functions for use on Cortex-M processor based devices.
+ *
+ * The library is divided into a number of functions each covering a specific category:
+ * - Basic math functions
+ * - Fast math functions
+ * - Complex math functions
+ * - Filters
+ * - Matrix functions
+ * - Transforms
+ * - Motor control functions
+ * - Statistical functions
+ * - Support functions
+ * - Interpolation functions
+ *
+ * The library has separate functions for operating on 8-bit integers, 16-bit integers,
+ * 32-bit integer and 32-bit floating-point values.
+ *
+ * Using the Library
+ * ------------
+ *
+ * The library installer contains prebuilt versions of the libraries in the Lib
folder.
+ * - arm_cortexM7lfdp_math.lib (Little endian and Double Precision Floating Point Unit on Cortex-M7)
+ * - arm_cortexM7bfdp_math.lib (Big endian and Double Precision Floating Point Unit on Cortex-M7)
+ * - arm_cortexM7lfsp_math.lib (Little endian and Single Precision Floating Point Unit on Cortex-M7)
+ * - arm_cortexM7bfsp_math.lib (Big endian and Single Precision Floating Point Unit on Cortex-M7)
+ * - arm_cortexM7l_math.lib (Little endian on Cortex-M7)
+ * - arm_cortexM7b_math.lib (Big endian on Cortex-M7)
+ * - arm_cortexM4lf_math.lib (Little endian and Floating Point Unit on Cortex-M4)
+ * - arm_cortexM4bf_math.lib (Big endian and Floating Point Unit on Cortex-M4)
+ * - arm_cortexM4l_math.lib (Little endian on Cortex-M4)
+ * - arm_cortexM4b_math.lib (Big endian on Cortex-M4)
+ * - arm_cortexM3l_math.lib (Little endian on Cortex-M3)
+ * - arm_cortexM3b_math.lib (Big endian on Cortex-M3)
+ * - arm_cortexM0l_math.lib (Little endian on Cortex-M0 / CortexM0+)
+ * - arm_cortexM0b_math.lib (Big endian on Cortex-M0 / CortexM0+)
+ *
+ * The library functions are declared in the public file arm_math.h
which is placed in the Include
folder.
+ * Simply include this file and link the appropriate library in the application and begin calling the library functions. The Library supports single
+ * public header file arm_math.h
for Cortex-M7/M4/M3/M0/M0+ with little endian and big endian. Same header file will be used for floating point unit(FPU) variants.
+ * Define the appropriate pre processor MACRO ARM_MATH_CM7 or ARM_MATH_CM4 or ARM_MATH_CM3 or
+ * ARM_MATH_CM0 or ARM_MATH_CM0PLUS depending on the target processor in the application.
+ *
+ * Examples
+ * --------
+ *
+ * The library ships with a number of examples which demonstrate how to use the library functions.
+ *
+ * Toolchain Support
+ * ------------
+ *
+ * The library has been developed and tested with MDK-ARM version 5.14.0.0
+ * The library is being tested in GCC and IAR toolchains and updates on this activity will be made available shortly.
+ *
+ * Building the Library
+ * ------------
+ *
+ * The library installer contains a project file to re build libraries on MDK-ARM Tool chain in the CMSIS\\DSP_Lib\\Source\\ARM
folder.
+ * - arm_cortexM_math.uvprojx
+ *
+ *
+ * The libraries can be built by opening the arm_cortexM_math.uvprojx project in MDK-ARM, selecting a specific target, and defining the optional pre processor MACROs detailed above.
+ *
+ * Pre-processor Macros
+ * ------------
+ *
+ * Each library project have differant pre-processor macros.
+ *
+ * - UNALIGNED_SUPPORT_DISABLE:
+ *
+ * Define macro UNALIGNED_SUPPORT_DISABLE, If the silicon does not support unaligned memory access
+ *
+ * - ARM_MATH_BIG_ENDIAN:
+ *
+ * Define macro ARM_MATH_BIG_ENDIAN to build the library for big endian targets. By default library builds for little endian targets.
+ *
+ * - ARM_MATH_MATRIX_CHECK:
+ *
+ * Define macro ARM_MATH_MATRIX_CHECK for checking on the input and output sizes of matrices
+ *
+ * - ARM_MATH_ROUNDING:
+ *
+ * Define macro ARM_MATH_ROUNDING for rounding on support functions
+ *
+ * - ARM_MATH_CMx:
+ *
+ * Define macro ARM_MATH_CM4 for building the library on Cortex-M4 target, ARM_MATH_CM3 for building library on Cortex-M3 target
+ * and ARM_MATH_CM0 for building library on Cortex-M0 target, ARM_MATH_CM0PLUS for building library on Cortex-M0+ target, and
+ * ARM_MATH_CM7 for building the library on cortex-M7.
+ *
+ * - __FPU_PRESENT:
+ *
+ * Initialize macro __FPU_PRESENT = 1 when building on FPU supported Targets. Enable this macro for M4bf and M4lf libraries
+ *
+ *
+ * CMSIS-DSP in ARM::CMSIS Pack
+ * -----------------------------
+ *
+ * The following files relevant to CMSIS-DSP are present in the ARM::CMSIS Pack directories:
+ * |File/Folder |Content |
+ * |------------------------------|------------------------------------------------------------------------|
+ * |\b CMSIS\\Documentation\\DSP | This documentation |
+ * |\b CMSIS\\DSP_Lib | Software license agreement (license.txt) |
+ * |\b CMSIS\\DSP_Lib\\Examples | Example projects demonstrating the usage of the library functions |
+ * |\b CMSIS\\DSP_Lib\\Source | Source files for rebuilding the library |
+ *
+ *
+ * Revision History of CMSIS-DSP
+ * ------------
+ * Please refer to \ref ChangeLog_pg.
+ *
+ * Copyright Notice
+ * ------------
+ *
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ */
+
+
+/**
+ * @defgroup groupMath Basic Math Functions
+ */
+
+/**
+ * @defgroup groupFastMath Fast Math Functions
+ * This set of functions provides a fast approximation to sine, cosine, and square root.
+ * As compared to most of the other functions in the CMSIS math library, the fast math functions
+ * operate on individual values and not arrays.
+ * There are separate functions for Q15, Q31, and floating-point data.
+ *
+ */
+
+/**
+ * @defgroup groupCmplxMath Complex Math Functions
+ * This set of functions operates on complex data vectors.
+ * The data in the complex arrays is stored in an interleaved fashion
+ * (real, imag, real, imag, ...).
+ * In the API functions, the number of samples in a complex array refers
+ * to the number of complex values; the array contains twice this number of
+ * real values.
+ */
+
+/**
+ * @defgroup groupFilters Filtering Functions
+ */
+
+/**
+ * @defgroup groupMatrix Matrix Functions
+ *
+ * This set of functions provides basic matrix math operations.
+ * The functions operate on matrix data structures. For example,
+ * the type
+ * definition for the floating-point matrix structure is shown
+ * below:
+ *
+ * typedef struct
+ * {
+ * uint16_t numRows; // number of rows of the matrix.
+ * uint16_t numCols; // number of columns of the matrix.
+ * float32_t *pData; // points to the data of the matrix.
+ * } arm_matrix_instance_f32;
+ *
+ * There are similar definitions for Q15 and Q31 data types.
+ *
+ * The structure specifies the size of the matrix and then points to
+ * an array of data. The array is of size numRows X numCols
+ * and the values are arranged in row order. That is, the
+ * matrix element (i, j) is stored at:
+ *
+ * pData[i*numCols + j]
+ *
+ *
+ * \par Init Functions
+ * There is an associated initialization function for each type of matrix
+ * data structure.
+ * The initialization function sets the values of the internal structure fields.
+ * Refer to the function arm_mat_init_f32()
, arm_mat_init_q31()
+ * and arm_mat_init_q15()
for floating-point, Q31 and Q15 types, respectively.
+ *
+ * \par
+ * Use of the initialization function is optional. However, if initialization function is used
+ * then the instance structure cannot be placed into a const data section.
+ * To place the instance structure in a const data
+ * section, manually initialize the data structure. For example:
+ *
+ * arm_matrix_instance_f32 S = {nRows, nColumns, pData};
+ * arm_matrix_instance_q31 S = {nRows, nColumns, pData};
+ * arm_matrix_instance_q15 S = {nRows, nColumns, pData};
+ *
+ * where nRows
specifies the number of rows, nColumns
+ * specifies the number of columns, and pData
points to the
+ * data array.
+ *
+ * \par Size Checking
+ * By default all of the matrix functions perform size checking on the input and
+ * output matrices. For example, the matrix addition function verifies that the
+ * two input matrices and the output matrix all have the same number of rows and
+ * columns. If the size check fails the functions return:
+ *
+ * ARM_MATH_SIZE_MISMATCH
+ *
+ * Otherwise the functions return
+ *
+ * ARM_MATH_SUCCESS
+ *
+ * There is some overhead associated with this matrix size checking.
+ * The matrix size checking is enabled via the \#define
+ *
+ * ARM_MATH_MATRIX_CHECK
+ *
+ * within the library project settings. By default this macro is defined
+ * and size checking is enabled. By changing the project settings and
+ * undefining this macro size checking is eliminated and the functions
+ * run a bit faster. With size checking disabled the functions always
+ * return ARM_MATH_SUCCESS
.
+ */
+
+/**
+ * @defgroup groupTransforms Transform Functions
+ */
+
+/**
+ * @defgroup groupController Controller Functions
+ */
+
+/**
+ * @defgroup groupStats Statistics Functions
+ */
+/**
+ * @defgroup groupSupport Support Functions
+ */
+
+/**
+ * @defgroup groupInterpolation Interpolation Functions
+ * These functions perform 1- and 2-dimensional interpolation of data.
+ * Linear interpolation is used for 1-dimensional data and
+ * bilinear interpolation is used for 2-dimensional data.
+ */
+
+/**
+ * @defgroup groupExamples Examples
+ */
+#ifndef _ARM_MATH_H
+#define _ARM_MATH_H
+
+/* 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
+
+#define __CMSIS_GENERIC /* disable NVIC and Systick functions */
+
+#if defined(ARM_MATH_CM7)
+ #include "core_cm7.h"
+#elif defined (ARM_MATH_CM4)
+ #include "core_cm4.h"
+#elif defined (ARM_MATH_CM3)
+ #include "core_cm3.h"
+#elif defined (ARM_MATH_CM0)
+ #include "core_cm0.h"
+ #define ARM_MATH_CM0_FAMILY
+#elif defined (ARM_MATH_CM0PLUS)
+ #include "core_cm0plus.h"
+ #define ARM_MATH_CM0_FAMILY
+#else
+ #error "Define according the used Cortex core ARM_MATH_CM7, ARM_MATH_CM4, ARM_MATH_CM3, ARM_MATH_CM0PLUS or ARM_MATH_CM0"
+#endif
+
+#undef __CMSIS_GENERIC /* enable NVIC and Systick functions */
+#include "string.h"
+#include "math.h"
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+ /**
+ * @brief Macros required for reciprocal calculation in Normalized LMS
+ */
+
+#define DELTA_Q31 (0x100)
+#define DELTA_Q15 0x5
+#define INDEX_MASK 0x0000003F
+#ifndef PI
+#define PI 3.14159265358979f
+#endif
+
+ /**
+ * @brief Macros required for SINE and COSINE Fast math approximations
+ */
+
+#define FAST_MATH_TABLE_SIZE 512
+#define FAST_MATH_Q31_SHIFT (32 - 10)
+#define FAST_MATH_Q15_SHIFT (16 - 10)
+#define CONTROLLER_Q31_SHIFT (32 - 9)
+#define TABLE_SIZE 256
+#define TABLE_SPACING_Q31 0x400000
+#define TABLE_SPACING_Q15 0x80
+
+ /**
+ * @brief Macros required for SINE and COSINE Controller functions
+ */
+ /* 1.31(q31) Fixed value of 2/360 */
+ /* -1 to +1 is divided into 360 values so total spacing is (2/360) */
+#define INPUT_SPACING 0xB60B61
+
+ /**
+ * @brief Macro for Unaligned Support
+ */
+#ifndef UNALIGNED_SUPPORT_DISABLE
+ #define ALIGN4
+#else
+ #if defined (__GNUC__)
+ #define ALIGN4 __attribute__((aligned(4)))
+ #else
+ #define ALIGN4 __align(4)
+ #endif
+#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
+
+ /**
+ * @brief Error status returned by some functions in the library.
+ */
+
+ typedef enum
+ {
+ ARM_MATH_SUCCESS = 0, /**< No error */
+ ARM_MATH_ARGUMENT_ERROR = -1, /**< One or more arguments are incorrect */
+ ARM_MATH_LENGTH_ERROR = -2, /**< Length of data buffer is incorrect */
+ ARM_MATH_SIZE_MISMATCH = -3, /**< Size of matrices is not compatible with the operation. */
+ ARM_MATH_NANINF = -4, /**< Not-a-number (NaN) or infinity is generated */
+ ARM_MATH_SINGULAR = -5, /**< Generated by matrix inversion if the input matrix is singular and cannot be inverted. */
+ ARM_MATH_TEST_FAILURE = -6 /**< Test Failed */
+ } arm_status;
+
+ /**
+ * @brief 8-bit fractional data type in 1.7 format.
+ */
+ typedef int8_t q7_t;
+
+ /**
+ * @brief 16-bit fractional data type in 1.15 format.
+ */
+ typedef int16_t q15_t;
+
+ /**
+ * @brief 32-bit fractional data type in 1.31 format.
+ */
+ typedef int32_t q31_t;
+
+ /**
+ * @brief 64-bit fractional data type in 1.63 format.
+ */
+ typedef int64_t q63_t;
+
+ /**
+ * @brief 32-bit floating-point type definition.
+ */
+ typedef float float32_t;
+
+ /**
+ * @brief 64-bit floating-point type definition.
+ */
+ typedef double float64_t;
+
+ /**
+ * @brief definition to read/write two 16 bit values.
+ */
+#if defined __CC_ARM
+ #define __SIMD32_TYPE int32_t __packed
+ #define CMSIS_UNUSED __attribute__((unused))
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #define __SIMD32_TYPE int32_t
+ #define CMSIS_UNUSED __attribute__((unused))
+
+#elif defined __GNUC__
+ #define __SIMD32_TYPE int32_t
+ #define CMSIS_UNUSED __attribute__((unused))
+
+#elif defined __ICCARM__
+ #define __SIMD32_TYPE int32_t __packed
+ #define CMSIS_UNUSED
+
+#elif defined __CSMC__
+ #define __SIMD32_TYPE int32_t
+ #define CMSIS_UNUSED
+
+#elif defined __TASKING__
+ #define __SIMD32_TYPE __unaligned int32_t
+ #define CMSIS_UNUSED
+
+#else
+ #error Unknown compiler
+#endif
+
+#define __SIMD32(addr) (*(__SIMD32_TYPE **) & (addr))
+#define __SIMD32_CONST(addr) ((__SIMD32_TYPE *)(addr))
+#define _SIMD32_OFFSET(addr) (*(__SIMD32_TYPE *) (addr))
+#define __SIMD64(addr) (*(int64_t **) & (addr))
+
+#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY)
+ /**
+ * @brief definition to pack two 16 bit values.
+ */
+#define __PKHBT(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0x0000FFFF) | \
+ (((int32_t)(ARG2) << ARG3) & (int32_t)0xFFFF0000) )
+#define __PKHTB(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0xFFFF0000) | \
+ (((int32_t)(ARG2) >> ARG3) & (int32_t)0x0000FFFF) )
+
+#endif
+
+
+ /**
+ * @brief definition to pack four 8 bit values.
+ */
+#ifndef ARM_MATH_BIG_ENDIAN
+
+#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v0) << 0) & (int32_t)0x000000FF) | \
+ (((int32_t)(v1) << 8) & (int32_t)0x0000FF00) | \
+ (((int32_t)(v2) << 16) & (int32_t)0x00FF0000) | \
+ (((int32_t)(v3) << 24) & (int32_t)0xFF000000) )
+#else
+
+#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v3) << 0) & (int32_t)0x000000FF) | \
+ (((int32_t)(v2) << 8) & (int32_t)0x0000FF00) | \
+ (((int32_t)(v1) << 16) & (int32_t)0x00FF0000) | \
+ (((int32_t)(v0) << 24) & (int32_t)0xFF000000) )
+
+#endif
+
+
+ /**
+ * @brief Clips Q63 to Q31 values.
+ */
+ static __INLINE q31_t clip_q63_to_q31(
+ q63_t x)
+ {
+ return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ?
+ ((0x7FFFFFFF ^ ((q31_t) (x >> 63)))) : (q31_t) x;
+ }
+
+ /**
+ * @brief Clips Q63 to Q15 values.
+ */
+ static __INLINE q15_t clip_q63_to_q15(
+ q63_t x)
+ {
+ return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ?
+ ((0x7FFF ^ ((q15_t) (x >> 63)))) : (q15_t) (x >> 15);
+ }
+
+ /**
+ * @brief Clips Q31 to Q7 values.
+ */
+ static __INLINE q7_t clip_q31_to_q7(
+ q31_t x)
+ {
+ return ((q31_t) (x >> 24) != ((q31_t) x >> 23)) ?
+ ((0x7F ^ ((q7_t) (x >> 31)))) : (q7_t) x;
+ }
+
+ /**
+ * @brief Clips Q31 to Q15 values.
+ */
+ static __INLINE q15_t clip_q31_to_q15(
+ q31_t x)
+ {
+ return ((q31_t) (x >> 16) != ((q31_t) x >> 15)) ?
+ ((0x7FFF ^ ((q15_t) (x >> 31)))) : (q15_t) x;
+ }
+
+ /**
+ * @brief Multiplies 32 X 64 and returns 32 bit result in 2.30 format.
+ */
+
+ static __INLINE q63_t mult32x64(
+ q63_t x,
+ q31_t y)
+ {
+ return ((((q63_t) (x & 0x00000000FFFFFFFF) * y) >> 32) +
+ (((q63_t) (x >> 32) * y)));
+ }
+
+/*
+ #if defined (ARM_MATH_CM0_FAMILY) && defined ( __CC_ARM )
+ #define __CLZ __clz
+ #endif
+ */
+/* note: function can be removed when all toolchain support __CLZ for Cortex-M0 */
+#if defined (ARM_MATH_CM0_FAMILY) && ((defined (__ICCARM__)) )
+ static __INLINE uint32_t __CLZ(
+ q31_t data);
+
+ static __INLINE uint32_t __CLZ(
+ q31_t data)
+ {
+ uint32_t count = 0;
+ uint32_t mask = 0x80000000;
+
+ while((data & mask) == 0)
+ {
+ count += 1u;
+ mask = mask >> 1u;
+ }
+
+ return (count);
+ }
+#endif
+
+ /**
+ * @brief Function to Calculates 1/in (reciprocal) value of Q31 Data type.
+ */
+
+ static __INLINE uint32_t arm_recip_q31(
+ q31_t in,
+ q31_t * dst,
+ q31_t * pRecipTable)
+ {
+ q31_t out;
+ uint32_t tempVal;
+ uint32_t index, i;
+ uint32_t signBits;
+
+ if(in > 0)
+ {
+ signBits = ((uint32_t) (__CLZ( in) - 1));
+ }
+ else
+ {
+ signBits = ((uint32_t) (__CLZ(-in) - 1));
+ }
+
+ /* Convert input sample to 1.31 format */
+ in = (in << signBits);
+
+ /* calculation of index for initial approximated Val */
+ index = (uint32_t)(in >> 24);
+ index = (index & INDEX_MASK);
+
+ /* 1.31 with exp 1 */
+ out = pRecipTable[index];
+
+ /* calculation of reciprocal value */
+ /* running approximation for two iterations */
+ for (i = 0u; i < 2u; i++)
+ {
+ tempVal = (uint32_t) (((q63_t) in * out) >> 31);
+ tempVal = 0x7FFFFFFFu - tempVal;
+ /* 1.31 with exp 1 */
+ /* out = (q31_t) (((q63_t) out * tempVal) >> 30); */
+ out = clip_q63_to_q31(((q63_t) out * tempVal) >> 30);
+ }
+
+ /* write output */
+ *dst = out;
+
+ /* return num of signbits of out = 1/in value */
+ return (signBits + 1u);
+ }
+
+
+ /**
+ * @brief Function to Calculates 1/in (reciprocal) value of Q15 Data type.
+ */
+ static __INLINE uint32_t arm_recip_q15(
+ q15_t in,
+ q15_t * dst,
+ q15_t * pRecipTable)
+ {
+ q15_t out = 0;
+ uint32_t tempVal = 0;
+ uint32_t index = 0, i = 0;
+ uint32_t signBits = 0;
+
+ if(in > 0)
+ {
+ signBits = ((uint32_t)(__CLZ( in) - 17));
+ }
+ else
+ {
+ signBits = ((uint32_t)(__CLZ(-in) - 17));
+ }
+
+ /* Convert input sample to 1.15 format */
+ in = (in << signBits);
+
+ /* calculation of index for initial approximated Val */
+ index = (uint32_t)(in >> 8);
+ index = (index & INDEX_MASK);
+
+ /* 1.15 with exp 1 */
+ out = pRecipTable[index];
+
+ /* calculation of reciprocal value */
+ /* running approximation for two iterations */
+ for (i = 0u; i < 2u; i++)
+ {
+ tempVal = (uint32_t) (((q31_t) in * out) >> 15);
+ tempVal = 0x7FFFu - tempVal;
+ /* 1.15 with exp 1 */
+ out = (q15_t) (((q31_t) out * tempVal) >> 14);
+ /* out = clip_q31_to_q15(((q31_t) out * tempVal) >> 14); */
+ }
+
+ /* write output */
+ *dst = out;
+
+ /* return num of signbits of out = 1/in value */
+ return (signBits + 1);
+ }
+
+
+ /*
+ * @brief C custom defined intrinisic function for only M0 processors
+ */
+#if defined(ARM_MATH_CM0_FAMILY)
+ static __INLINE q31_t __SSAT(
+ q31_t x,
+ uint32_t y)
+ {
+ int32_t posMax, negMin;
+ uint32_t i;
+
+ posMax = 1;
+ for (i = 0; i < (y - 1); i++)
+ {
+ posMax = posMax * 2;
+ }
+
+ if(x > 0)
+ {
+ posMax = (posMax - 1);
+
+ if(x > posMax)
+ {
+ x = posMax;
+ }
+ }
+ else
+ {
+ negMin = -posMax;
+
+ if(x < negMin)
+ {
+ x = negMin;
+ }
+ }
+ return (x);
+ }
+#endif /* end of ARM_MATH_CM0_FAMILY */
+
+
+ /*
+ * @brief C custom defined intrinsic function for M3 and M0 processors
+ */
+#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY)
+
+ /*
+ * @brief C custom defined QADD8 for M3 and M0 processors
+ */
+ static __INLINE uint32_t __QADD8(
+ uint32_t x,
+ uint32_t y)
+ {
+ q31_t r, s, t, u;
+
+ r = __SSAT(((((q31_t)x << 24) >> 24) + (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF;
+ s = __SSAT(((((q31_t)x << 16) >> 24) + (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF;
+ t = __SSAT(((((q31_t)x << 8) >> 24) + (((q31_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF;
+ u = __SSAT(((((q31_t)x ) >> 24) + (((q31_t)y ) >> 24)), 8) & (int32_t)0x000000FF;
+
+ return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r )));
+ }
+
+
+ /*
+ * @brief C custom defined QSUB8 for M3 and M0 processors
+ */
+ static __INLINE uint32_t __QSUB8(
+ uint32_t x,
+ uint32_t y)
+ {
+ q31_t r, s, t, u;
+
+ r = __SSAT(((((q31_t)x << 24) >> 24) - (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF;
+ s = __SSAT(((((q31_t)x << 16) >> 24) - (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF;
+ t = __SSAT(((((q31_t)x << 8) >> 24) - (((q31_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF;
+ u = __SSAT(((((q31_t)x ) >> 24) - (((q31_t)y ) >> 24)), 8) & (int32_t)0x000000FF;
+
+ return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r )));
+ }
+
+
+ /*
+ * @brief C custom defined QADD16 for M3 and M0 processors
+ */
+ static __INLINE uint32_t __QADD16(
+ uint32_t x,
+ uint32_t y)
+ {
+/* q31_t r, s; without initialisation 'arm_offset_q15 test' fails but 'intrinsic' tests pass! for armCC */
+ q31_t r = 0, s = 0;
+
+ r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF;
+ s = __SSAT(((((q31_t)x ) >> 16) + (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF;
+
+ return ((uint32_t)((s << 16) | (r )));
+ }
+
+
+ /*
+ * @brief C custom defined SHADD16 for M3 and M0 processors
+ */
+ static __INLINE uint32_t __SHADD16(
+ uint32_t x,
+ uint32_t y)
+ {
+ q31_t r, s;
+
+ r = (((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+ s = (((((q31_t)x ) >> 16) + (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+
+ return ((uint32_t)((s << 16) | (r )));
+ }
+
+
+ /*
+ * @brief C custom defined QSUB16 for M3 and M0 processors
+ */
+ static __INLINE uint32_t __QSUB16(
+ uint32_t x,
+ uint32_t y)
+ {
+ q31_t r, s;
+
+ r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF;
+ s = __SSAT(((((q31_t)x ) >> 16) - (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF;
+
+ return ((uint32_t)((s << 16) | (r )));
+ }
+
+
+ /*
+ * @brief C custom defined SHSUB16 for M3 and M0 processors
+ */
+ static __INLINE uint32_t __SHSUB16(
+ uint32_t x,
+ uint32_t y)
+ {
+ q31_t r, s;
+
+ r = (((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+ s = (((((q31_t)x ) >> 16) - (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+
+ return ((uint32_t)((s << 16) | (r )));
+ }
+
+
+ /*
+ * @brief C custom defined QASX for M3 and M0 processors
+ */
+ static __INLINE uint32_t __QASX(
+ uint32_t x,
+ uint32_t y)
+ {
+ q31_t r, s;
+
+ r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF;
+ s = __SSAT(((((q31_t)x ) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF;
+
+ return ((uint32_t)((s << 16) | (r )));
+ }
+
+
+ /*
+ * @brief C custom defined SHASX for M3 and M0 processors
+ */
+ static __INLINE uint32_t __SHASX(
+ uint32_t x,
+ uint32_t y)
+ {
+ q31_t r, s;
+
+ r = (((((q31_t)x << 16) >> 16) - (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+ s = (((((q31_t)x ) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+
+ return ((uint32_t)((s << 16) | (r )));
+ }
+
+
+ /*
+ * @brief C custom defined QSAX for M3 and M0 processors
+ */
+ static __INLINE uint32_t __QSAX(
+ uint32_t x,
+ uint32_t y)
+ {
+ q31_t r, s;
+
+ r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF;
+ s = __SSAT(((((q31_t)x ) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF;
+
+ return ((uint32_t)((s << 16) | (r )));
+ }
+
+
+ /*
+ * @brief C custom defined SHSAX for M3 and M0 processors
+ */
+ static __INLINE uint32_t __SHSAX(
+ uint32_t x,
+ uint32_t y)
+ {
+ q31_t r, s;
+
+ r = (((((q31_t)x << 16) >> 16) + (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+ s = (((((q31_t)x ) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+
+ return ((uint32_t)((s << 16) | (r )));
+ }
+
+
+ /*
+ * @brief C custom defined SMUSDX for M3 and M0 processors
+ */
+ static __INLINE uint32_t __SMUSDX(
+ uint32_t x,
+ uint32_t y)
+ {
+ return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) -
+ ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) ));
+ }
+
+ /*
+ * @brief C custom defined SMUADX for M3 and M0 processors
+ */
+ static __INLINE uint32_t __SMUADX(
+ uint32_t x,
+ uint32_t y)
+ {
+ return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) +
+ ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) ));
+ }
+
+
+ /*
+ * @brief C custom defined QADD for M3 and M0 processors
+ */
+ static __INLINE int32_t __QADD(
+ int32_t x,
+ int32_t y)
+ {
+ return ((int32_t)(clip_q63_to_q31((q63_t)x + (q31_t)y)));
+ }
+
+
+ /*
+ * @brief C custom defined QSUB for M3 and M0 processors
+ */
+ static __INLINE int32_t __QSUB(
+ int32_t x,
+ int32_t y)
+ {
+ return ((int32_t)(clip_q63_to_q31((q63_t)x - (q31_t)y)));
+ }
+
+
+ /*
+ * @brief C custom defined SMLAD for M3 and M0 processors
+ */
+ static __INLINE uint32_t __SMLAD(
+ uint32_t x,
+ uint32_t y,
+ uint32_t sum)
+ {
+ return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) +
+ ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) +
+ ( ((q31_t)sum ) ) ));
+ }
+
+
+ /*
+ * @brief C custom defined SMLADX for M3 and M0 processors
+ */
+ static __INLINE uint32_t __SMLADX(
+ uint32_t x,
+ uint32_t y,
+ uint32_t sum)
+ {
+ return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) +
+ ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) +
+ ( ((q31_t)sum ) ) ));
+ }
+
+
+ /*
+ * @brief C custom defined SMLSDX for M3 and M0 processors
+ */
+ static __INLINE uint32_t __SMLSDX(
+ uint32_t x,
+ uint32_t y,
+ uint32_t sum)
+ {
+ return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) -
+ ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) +
+ ( ((q31_t)sum ) ) ));
+ }
+
+
+ /*
+ * @brief C custom defined SMLALD for M3 and M0 processors
+ */
+ static __INLINE uint64_t __SMLALD(
+ uint32_t x,
+ uint32_t y,
+ uint64_t sum)
+ {
+/* return (sum + ((q15_t) (x >> 16) * (q15_t) (y >> 16)) + ((q15_t) x * (q15_t) y)); */
+ return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) +
+ ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) +
+ ( ((q63_t)sum ) ) ));
+ }
+
+
+ /*
+ * @brief C custom defined SMLALDX for M3 and M0 processors
+ */
+ static __INLINE uint64_t __SMLALDX(
+ uint32_t x,
+ uint32_t y,
+ uint64_t sum)
+ {
+/* return (sum + ((q15_t) (x >> 16) * (q15_t) y)) + ((q15_t) x * (q15_t) (y >> 16)); */
+ return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) +
+ ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) +
+ ( ((q63_t)sum ) ) ));
+ }
+
+
+ /*
+ * @brief C custom defined SMUAD for M3 and M0 processors
+ */
+ static __INLINE uint32_t __SMUAD(
+ uint32_t x,
+ uint32_t y)
+ {
+ return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) +
+ ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) ));
+ }
+
+
+ /*
+ * @brief C custom defined SMUSD for M3 and M0 processors
+ */
+ static __INLINE uint32_t __SMUSD(
+ uint32_t x,
+ uint32_t y)
+ {
+ return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) -
+ ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) ));
+ }
+
+
+ /*
+ * @brief C custom defined SXTB16 for M3 and M0 processors
+ */
+ static __INLINE uint32_t __SXTB16(
+ uint32_t x)
+ {
+ return ((uint32_t)(((((q31_t)x << 24) >> 24) & (q31_t)0x0000FFFF) |
+ ((((q31_t)x << 8) >> 8) & (q31_t)0xFFFF0000) ));
+ }
+
+#endif /* defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) */
+
+
+ /**
+ * @brief Instance structure for the Q7 FIR filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of filter coefficients in the filter. */
+ q7_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+ q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/
+ } arm_fir_instance_q7;
+
+ /**
+ * @brief Instance structure for the Q15 FIR filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of filter coefficients in the filter. */
+ q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+ q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/
+ } arm_fir_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q31 FIR filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of filter coefficients in the filter. */
+ q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+ q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */
+ } arm_fir_instance_q31;
+
+ /**
+ * @brief Instance structure for the floating-point FIR filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of filter coefficients in the filter. */
+ float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+ float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */
+ } arm_fir_instance_f32;
+
+
+ /**
+ * @brief Processing function for the Q7 FIR filter.
+ * @param[in] S points to an instance of the Q7 FIR filter structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_fir_q7(
+ const arm_fir_instance_q7 * S,
+ q7_t * pSrc,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the Q7 FIR filter.
+ * @param[in,out] S points to an instance of the Q7 FIR structure.
+ * @param[in] numTaps Number of filter coefficients in the filter.
+ * @param[in] pCoeffs points to the filter coefficients.
+ * @param[in] pState points to the state buffer.
+ * @param[in] blockSize number of samples that are processed.
+ */
+ void arm_fir_init_q7(
+ arm_fir_instance_q7 * S,
+ uint16_t numTaps,
+ q7_t * pCoeffs,
+ q7_t * pState,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the Q15 FIR filter.
+ * @param[in] S points to an instance of the Q15 FIR structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_fir_q15(
+ const arm_fir_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the fast Q15 FIR filter for Cortex-M3 and Cortex-M4.
+ * @param[in] S points to an instance of the Q15 FIR filter structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_fir_fast_q15(
+ const arm_fir_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the Q15 FIR filter.
+ * @param[in,out] S points to an instance of the Q15 FIR filter structure.
+ * @param[in] numTaps Number of filter coefficients in the filter. Must be even and greater than or equal to 4.
+ * @param[in] pCoeffs points to the filter coefficients.
+ * @param[in] pState points to the state buffer.
+ * @param[in] blockSize number of samples that are processed at a time.
+ * @return The function returns ARM_MATH_SUCCESS if initialization was successful or ARM_MATH_ARGUMENT_ERROR if
+ * numTaps
is not a supported value.
+ */
+ arm_status arm_fir_init_q15(
+ arm_fir_instance_q15 * S,
+ uint16_t numTaps,
+ q15_t * pCoeffs,
+ q15_t * pState,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the Q31 FIR filter.
+ * @param[in] S points to an instance of the Q31 FIR filter structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_fir_q31(
+ const arm_fir_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the fast Q31 FIR filter for Cortex-M3 and Cortex-M4.
+ * @param[in] S points to an instance of the Q31 FIR structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_fir_fast_q31(
+ const arm_fir_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the Q31 FIR filter.
+ * @param[in,out] S points to an instance of the Q31 FIR structure.
+ * @param[in] numTaps Number of filter coefficients in the filter.
+ * @param[in] pCoeffs points to the filter coefficients.
+ * @param[in] pState points to the state buffer.
+ * @param[in] blockSize number of samples that are processed at a time.
+ */
+ void arm_fir_init_q31(
+ arm_fir_instance_q31 * S,
+ uint16_t numTaps,
+ q31_t * pCoeffs,
+ q31_t * pState,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the floating-point FIR filter.
+ * @param[in] S points to an instance of the floating-point FIR structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_fir_f32(
+ const arm_fir_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the floating-point FIR filter.
+ * @param[in,out] S points to an instance of the floating-point FIR filter structure.
+ * @param[in] numTaps Number of filter coefficients in the filter.
+ * @param[in] pCoeffs points to the filter coefficients.
+ * @param[in] pState points to the state buffer.
+ * @param[in] blockSize number of samples that are processed at a time.
+ */
+ void arm_fir_init_f32(
+ arm_fir_instance_f32 * S,
+ uint16_t numTaps,
+ float32_t * pCoeffs,
+ float32_t * pState,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Instance structure for the Q15 Biquad cascade filter.
+ */
+ typedef struct
+ {
+ int8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */
+ q15_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */
+ q15_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */
+ int8_t postShift; /**< Additional shift, in bits, applied to each output sample. */
+ } arm_biquad_casd_df1_inst_q15;
+
+ /**
+ * @brief Instance structure for the Q31 Biquad cascade filter.
+ */
+ typedef struct
+ {
+ uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */
+ q31_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */
+ q31_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */
+ uint8_t postShift; /**< Additional shift, in bits, applied to each output sample. */
+ } arm_biquad_casd_df1_inst_q31;
+
+ /**
+ * @brief Instance structure for the floating-point Biquad cascade filter.
+ */
+ typedef struct
+ {
+ uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */
+ float32_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */
+ float32_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */
+ } arm_biquad_casd_df1_inst_f32;
+
+
+ /**
+ * @brief Processing function for the Q15 Biquad cascade filter.
+ * @param[in] S points to an instance of the Q15 Biquad cascade structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_biquad_cascade_df1_q15(
+ const arm_biquad_casd_df1_inst_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the Q15 Biquad cascade filter.
+ * @param[in,out] S points to an instance of the Q15 Biquad cascade structure.
+ * @param[in] numStages number of 2nd order stages in the filter.
+ * @param[in] pCoeffs points to the filter coefficients.
+ * @param[in] pState points to the state buffer.
+ * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format
+ */
+ void arm_biquad_cascade_df1_init_q15(
+ arm_biquad_casd_df1_inst_q15 * S,
+ uint8_t numStages,
+ q15_t * pCoeffs,
+ q15_t * pState,
+ int8_t postShift);
+
+
+ /**
+ * @brief Fast but less precise processing function for the Q15 Biquad cascade filter for Cortex-M3 and Cortex-M4.
+ * @param[in] S points to an instance of the Q15 Biquad cascade structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_biquad_cascade_df1_fast_q15(
+ const arm_biquad_casd_df1_inst_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the Q31 Biquad cascade filter
+ * @param[in] S points to an instance of the Q31 Biquad cascade structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_biquad_cascade_df1_q31(
+ const arm_biquad_casd_df1_inst_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Fast but less precise processing function for the Q31 Biquad cascade filter for Cortex-M3 and Cortex-M4.
+ * @param[in] S points to an instance of the Q31 Biquad cascade structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_biquad_cascade_df1_fast_q31(
+ const arm_biquad_casd_df1_inst_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the Q31 Biquad cascade filter.
+ * @param[in,out] S points to an instance of the Q31 Biquad cascade structure.
+ * @param[in] numStages number of 2nd order stages in the filter.
+ * @param[in] pCoeffs points to the filter coefficients.
+ * @param[in] pState points to the state buffer.
+ * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format
+ */
+ void arm_biquad_cascade_df1_init_q31(
+ arm_biquad_casd_df1_inst_q31 * S,
+ uint8_t numStages,
+ q31_t * pCoeffs,
+ q31_t * pState,
+ int8_t postShift);
+
+
+ /**
+ * @brief Processing function for the floating-point Biquad cascade filter.
+ * @param[in] S points to an instance of the floating-point Biquad cascade structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_biquad_cascade_df1_f32(
+ const arm_biquad_casd_df1_inst_f32 * S,
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the floating-point Biquad cascade filter.
+ * @param[in,out] S points to an instance of the floating-point Biquad cascade structure.
+ * @param[in] numStages number of 2nd order stages in the filter.
+ * @param[in] pCoeffs points to the filter coefficients.
+ * @param[in] pState points to the state buffer.
+ */
+ void arm_biquad_cascade_df1_init_f32(
+ arm_biquad_casd_df1_inst_f32 * S,
+ uint8_t numStages,
+ float32_t * pCoeffs,
+ float32_t * pState);
+
+
+ /**
+ * @brief Instance structure for the floating-point matrix structure.
+ */
+ typedef struct
+ {
+ uint16_t numRows; /**< number of rows of the matrix. */
+ uint16_t numCols; /**< number of columns of the matrix. */
+ float32_t *pData; /**< points to the data of the matrix. */
+ } arm_matrix_instance_f32;
+
+
+ /**
+ * @brief Instance structure for the floating-point matrix structure.
+ */
+ typedef struct
+ {
+ uint16_t numRows; /**< number of rows of the matrix. */
+ uint16_t numCols; /**< number of columns of the matrix. */
+ float64_t *pData; /**< points to the data of the matrix. */
+ } arm_matrix_instance_f64;
+
+ /**
+ * @brief Instance structure for the Q15 matrix structure.
+ */
+ typedef struct
+ {
+ uint16_t numRows; /**< number of rows of the matrix. */
+ uint16_t numCols; /**< number of columns of the matrix. */
+ q15_t *pData; /**< points to the data of the matrix. */
+ } arm_matrix_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q31 matrix structure.
+ */
+ typedef struct
+ {
+ uint16_t numRows; /**< number of rows of the matrix. */
+ uint16_t numCols; /**< number of columns of the matrix. */
+ q31_t *pData; /**< points to the data of the matrix. */
+ } arm_matrix_instance_q31;
+
+
+ /**
+ * @brief Floating-point matrix addition.
+ * @param[in] pSrcA points to the first input matrix structure
+ * @param[in] pSrcB points to the second input matrix structure
+ * @param[out] pDst points to output matrix structure
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH
or ARM_MATH_SUCCESS
based on the outcome of size checking.
+ */
+ arm_status arm_mat_add_f32(
+ const arm_matrix_instance_f32 * pSrcA,
+ const arm_matrix_instance_f32 * pSrcB,
+ arm_matrix_instance_f32 * pDst);
+
+
+ /**
+ * @brief Q15 matrix addition.
+ * @param[in] pSrcA points to the first input matrix structure
+ * @param[in] pSrcB points to the second input matrix structure
+ * @param[out] pDst points to output matrix structure
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH
or ARM_MATH_SUCCESS
based on the outcome of size checking.
+ */
+ arm_status arm_mat_add_q15(
+ const arm_matrix_instance_q15 * pSrcA,
+ const arm_matrix_instance_q15 * pSrcB,
+ arm_matrix_instance_q15 * pDst);
+
+
+ /**
+ * @brief Q31 matrix addition.
+ * @param[in] pSrcA points to the first input matrix structure
+ * @param[in] pSrcB points to the second input matrix structure
+ * @param[out] pDst points to output matrix structure
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH
or ARM_MATH_SUCCESS
based on the outcome of size checking.
+ */
+ arm_status arm_mat_add_q31(
+ const arm_matrix_instance_q31 * pSrcA,
+ const arm_matrix_instance_q31 * pSrcB,
+ arm_matrix_instance_q31 * pDst);
+
+
+ /**
+ * @brief Floating-point, complex, 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_cmplx_mult_f32(
+ const arm_matrix_instance_f32 * pSrcA,
+ const arm_matrix_instance_f32 * pSrcB,
+ arm_matrix_instance_f32 * pDst);
+
+
+ /**
+ * @brief Q15, complex, 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_cmplx_mult_q15(
+ const arm_matrix_instance_q15 * pSrcA,
+ const arm_matrix_instance_q15 * pSrcB,
+ arm_matrix_instance_q15 * pDst,
+ q15_t * pScratch);
+
+
+ /**
+ * @brief Q31, complex, 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_cmplx_mult_q31(
+ const arm_matrix_instance_q31 * pSrcA,
+ const arm_matrix_instance_q31 * pSrcB,
+ arm_matrix_instance_q31 * pDst);
+
+
+ /**
+ * @brief Floating-point matrix transpose.
+ * @param[in] pSrc points to the input matrix
+ * @param[out] pDst points to the output matrix
+ * @return The function returns either ARM_MATH_SIZE_MISMATCH
+ * or ARM_MATH_SUCCESS
based on the outcome of size checking.
+ */
+ arm_status arm_mat_trans_f32(
+ const arm_matrix_instance_f32 * pSrc,
+ arm_matrix_instance_f32 * pDst);
+
+
+ /**
+ * @brief Q15 matrix transpose.
+ * @param[in] pSrc points to the input matrix
+ * @param[out] pDst points to the output matrix
+ * @return The function returns either ARM_MATH_SIZE_MISMATCH
+ * or ARM_MATH_SUCCESS
based on the outcome of size checking.
+ */
+ arm_status arm_mat_trans_q15(
+ const arm_matrix_instance_q15 * pSrc,
+ arm_matrix_instance_q15 * pDst);
+
+
+ /**
+ * @brief Q31 matrix transpose.
+ * @param[in] pSrc points to the input matrix
+ * @param[out] pDst points to the output matrix
+ * @return The function returns either ARM_MATH_SIZE_MISMATCH
+ * or ARM_MATH_SUCCESS
based on the outcome of size checking.
+ */
+ arm_status arm_mat_trans_q31(
+ const arm_matrix_instance_q31 * pSrc,
+ arm_matrix_instance_q31 * pDst);
+
+
+ /**
+ * @brief Floating-point matrix multiplication
+ * @param[in] pSrcA points to the first input matrix structure
+ * @param[in] pSrcB points to the second input matrix structure
+ * @param[out] pDst points to output matrix structure
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH
or ARM_MATH_SUCCESS
based on the outcome of size checking.
+ */
+ arm_status arm_mat_mult_f32(
+ const arm_matrix_instance_f32 * pSrcA,
+ const arm_matrix_instance_f32 * pSrcB,
+ arm_matrix_instance_f32 * pDst);
+
+
+ /**
+ * @brief Q15 matrix multiplication
+ * @param[in] pSrcA points to the first input matrix structure
+ * @param[in] pSrcB points to the second input matrix structure
+ * @param[out] pDst points to output matrix structure
+ * @param[in] pState points to the array for storing intermediate results
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH
or ARM_MATH_SUCCESS
based on the outcome of size checking.
+ */
+ arm_status arm_mat_mult_q15(
+ const arm_matrix_instance_q15 * pSrcA,
+ const arm_matrix_instance_q15 * pSrcB,
+ arm_matrix_instance_q15 * pDst,
+ q15_t * pState);
+
+
+ /**
+ * @brief Q15 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4
+ * @param[in] pSrcA points to the first input matrix structure
+ * @param[in] pSrcB points to the second input matrix structure
+ * @param[out] pDst points to output matrix structure
+ * @param[in] pState points to the array for storing intermediate results
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH
or ARM_MATH_SUCCESS
based on the outcome of size checking.
+ */
+ arm_status arm_mat_mult_fast_q15(
+ const arm_matrix_instance_q15 * pSrcA,
+ const arm_matrix_instance_q15 * pSrcB,
+ arm_matrix_instance_q15 * pDst,
+ q15_t * pState);
+
+
+ /**
+ * @brief Q31 matrix multiplication
+ * @param[in] pSrcA points to the first input matrix structure
+ * @param[in] pSrcB points to the second input matrix structure
+ * @param[out] pDst points to output matrix structure
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH
or ARM_MATH_SUCCESS
based on the outcome of size checking.
+ */
+ arm_status arm_mat_mult_q31(
+ const arm_matrix_instance_q31 * pSrcA,
+ const arm_matrix_instance_q31 * pSrcB,
+ arm_matrix_instance_q31 * pDst);
+
+
+ /**
+ * @brief Q31 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4
+ * @param[in] pSrcA points to the first input matrix structure
+ * @param[in] pSrcB points to the second input matrix structure
+ * @param[out] pDst points to output matrix structure
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH
or ARM_MATH_SUCCESS
based on the outcome of size checking.
+ */
+ arm_status arm_mat_mult_fast_q31(
+ const arm_matrix_instance_q31 * pSrcA,
+ const arm_matrix_instance_q31 * pSrcB,
+ arm_matrix_instance_q31 * pDst);
+
+
+ /**
+ * @brief Floating-point matrix subtraction
+ * @param[in] pSrcA points to the first input matrix structure
+ * @param[in] pSrcB points to the second input matrix structure
+ * @param[out] pDst points to output matrix structure
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH
or ARM_MATH_SUCCESS
based on the outcome of size checking.
+ */
+ arm_status arm_mat_sub_f32(
+ const arm_matrix_instance_f32 * pSrcA,
+ const arm_matrix_instance_f32 * pSrcB,
+ arm_matrix_instance_f32 * pDst);
+
+
+ /**
+ * @brief Q15 matrix subtraction
+ * @param[in] pSrcA points to the first input matrix structure
+ * @param[in] pSrcB points to the second input matrix structure
+ * @param[out] pDst points to output matrix structure
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH
or ARM_MATH_SUCCESS
based on the outcome of size checking.
+ */
+ arm_status arm_mat_sub_q15(
+ const arm_matrix_instance_q15 * pSrcA,
+ const arm_matrix_instance_q15 * pSrcB,
+ arm_matrix_instance_q15 * pDst);
+
+
+ /**
+ * @brief Q31 matrix subtraction
+ * @param[in] pSrcA points to the first input matrix structure
+ * @param[in] pSrcB points to the second input matrix structure
+ * @param[out] pDst points to output matrix structure
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH
or ARM_MATH_SUCCESS
based on the outcome of size checking.
+ */
+ arm_status arm_mat_sub_q31(
+ const arm_matrix_instance_q31 * pSrcA,
+ const arm_matrix_instance_q31 * pSrcB,
+ arm_matrix_instance_q31 * pDst);
+
+
+ /**
+ * @brief Floating-point matrix scaling.
+ * @param[in] pSrc points to the input matrix
+ * @param[in] scale scale factor
+ * @param[out] pDst points to the output matrix
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH
or ARM_MATH_SUCCESS
based on the outcome of size checking.
+ */
+ arm_status arm_mat_scale_f32(
+ const arm_matrix_instance_f32 * pSrc,
+ float32_t scale,
+ arm_matrix_instance_f32 * pDst);
+
+
+ /**
+ * @brief Q15 matrix scaling.
+ * @param[in] pSrc points to input matrix
+ * @param[in] scaleFract fractional portion of the scale factor
+ * @param[in] shift number of bits to shift the result by
+ * @param[out] pDst points to output matrix
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH
or ARM_MATH_SUCCESS
based on the outcome of size checking.
+ */
+ arm_status arm_mat_scale_q15(
+ const arm_matrix_instance_q15 * pSrc,
+ q15_t scaleFract,
+ int32_t shift,
+ arm_matrix_instance_q15 * pDst);
+
+
+ /**
+ * @brief Q31 matrix scaling.
+ * @param[in] pSrc points to input matrix
+ * @param[in] scaleFract fractional portion of the scale factor
+ * @param[in] shift number of bits to shift the result by
+ * @param[out] pDst points to output matrix structure
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH
or ARM_MATH_SUCCESS
based on the outcome of size checking.
+ */
+ arm_status arm_mat_scale_q31(
+ const arm_matrix_instance_q31 * pSrc,
+ q31_t scaleFract,
+ int32_t shift,
+ arm_matrix_instance_q31 * pDst);
+
+
+ /**
+ * @brief Q31 matrix initialization.
+ * @param[in,out] S points to an instance of the floating-point matrix structure.
+ * @param[in] nRows number of rows in the matrix.
+ * @param[in] nColumns number of columns in the matrix.
+ * @param[in] pData points to the matrix data array.
+ */
+ void arm_mat_init_q31(
+ arm_matrix_instance_q31 * S,
+ uint16_t nRows,
+ uint16_t nColumns,
+ q31_t * pData);
+
+
+ /**
+ * @brief Q15 matrix initialization.
+ * @param[in,out] S points to an instance of the floating-point matrix structure.
+ * @param[in] nRows number of rows in the matrix.
+ * @param[in] nColumns number of columns in the matrix.
+ * @param[in] pData points to the matrix data array.
+ */
+ void arm_mat_init_q15(
+ arm_matrix_instance_q15 * S,
+ uint16_t nRows,
+ uint16_t nColumns,
+ q15_t * pData);
+
+
+ /**
+ * @brief Floating-point matrix initialization.
+ * @param[in,out] S points to an instance of the floating-point matrix structure.
+ * @param[in] nRows number of rows in the matrix.
+ * @param[in] nColumns number of columns in the matrix.
+ * @param[in] pData points to the matrix data array.
+ */
+ void arm_mat_init_f32(
+ arm_matrix_instance_f32 * S,
+ uint16_t nRows,
+ uint16_t nColumns,
+ float32_t * pData);
+
+
+
+ /**
+ * @brief Instance structure for the Q15 PID Control.
+ */
+ typedef struct
+ {
+ q15_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */
+#ifdef ARM_MATH_CM0_FAMILY
+ q15_t A1;
+ q15_t A2;
+#else
+ q31_t A1; /**< The derived gain A1 = -Kp - 2Kd | Kd.*/
+#endif
+ q15_t state[3]; /**< The state array of length 3. */
+ q15_t Kp; /**< The proportional gain. */
+ q15_t Ki; /**< The integral gain. */
+ q15_t Kd; /**< The derivative gain. */
+ } arm_pid_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q31 PID Control.
+ */
+ typedef struct
+ {
+ q31_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */
+ q31_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */
+ q31_t A2; /**< The derived gain, A2 = Kd . */
+ q31_t state[3]; /**< The state array of length 3. */
+ q31_t Kp; /**< The proportional gain. */
+ q31_t Ki; /**< The integral gain. */
+ q31_t Kd; /**< The derivative gain. */
+ } arm_pid_instance_q31;
+
+ /**
+ * @brief Instance structure for the floating-point PID Control.
+ */
+ typedef struct
+ {
+ float32_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */
+ float32_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */
+ float32_t A2; /**< The derived gain, A2 = Kd . */
+ float32_t state[3]; /**< The state array of length 3. */
+ float32_t Kp; /**< The proportional gain. */
+ float32_t Ki; /**< The integral gain. */
+ float32_t Kd; /**< The derivative gain. */
+ } arm_pid_instance_f32;
+
+
+
+ /**
+ * @brief Initialization function for the floating-point PID Control.
+ * @param[in,out] S points to an instance of the PID structure.
+ * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state.
+ */
+ void arm_pid_init_f32(
+ arm_pid_instance_f32 * S,
+ int32_t resetStateFlag);
+
+
+ /**
+ * @brief Reset function for the floating-point PID Control.
+ * @param[in,out] S is an instance of the floating-point PID Control structure
+ */
+ void arm_pid_reset_f32(
+ arm_pid_instance_f32 * S);
+
+
+ /**
+ * @brief Initialization function for the Q31 PID Control.
+ * @param[in,out] S points to an instance of the Q15 PID structure.
+ * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state.
+ */
+ void arm_pid_init_q31(
+ arm_pid_instance_q31 * S,
+ int32_t resetStateFlag);
+
+
+ /**
+ * @brief Reset function for the Q31 PID Control.
+ * @param[in,out] S points to an instance of the Q31 PID Control structure
+ */
+
+ void arm_pid_reset_q31(
+ arm_pid_instance_q31 * S);
+
+
+ /**
+ * @brief Initialization function for the Q15 PID Control.
+ * @param[in,out] S points to an instance of the Q15 PID structure.
+ * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state.
+ */
+ void arm_pid_init_q15(
+ arm_pid_instance_q15 * S,
+ int32_t resetStateFlag);
+
+
+ /**
+ * @brief Reset function for the Q15 PID Control.
+ * @param[in,out] S points to an instance of the q15 PID Control structure
+ */
+ void arm_pid_reset_q15(
+ arm_pid_instance_q15 * S);
+
+
+ /**
+ * @brief Instance structure for the floating-point Linear Interpolate function.
+ */
+ typedef struct
+ {
+ uint32_t nValues; /**< nValues */
+ float32_t x1; /**< x1 */
+ float32_t xSpacing; /**< xSpacing */
+ float32_t *pYData; /**< pointer to the table of Y values */
+ } arm_linear_interp_instance_f32;
+
+ /**
+ * @brief Instance structure for the floating-point bilinear interpolation function.
+ */
+ typedef struct
+ {
+ uint16_t numRows; /**< number of rows in the data table. */
+ uint16_t numCols; /**< number of columns in the data table. */
+ float32_t *pData; /**< points to the data table. */
+ } arm_bilinear_interp_instance_f32;
+
+ /**
+ * @brief Instance structure for the Q31 bilinear interpolation function.
+ */
+ typedef struct
+ {
+ uint16_t numRows; /**< number of rows in the data table. */
+ uint16_t numCols; /**< number of columns in the data table. */
+ q31_t *pData; /**< points to the data table. */
+ } arm_bilinear_interp_instance_q31;
+
+ /**
+ * @brief Instance structure for the Q15 bilinear interpolation function.
+ */
+ typedef struct
+ {
+ uint16_t numRows; /**< number of rows in the data table. */
+ uint16_t numCols; /**< number of columns in the data table. */
+ q15_t *pData; /**< points to the data table. */
+ } arm_bilinear_interp_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q15 bilinear interpolation function.
+ */
+ typedef struct
+ {
+ uint16_t numRows; /**< number of rows in the data table. */
+ uint16_t numCols; /**< number of columns in the data table. */
+ q7_t *pData; /**< points to the data table. */
+ } arm_bilinear_interp_instance_q7;
+
+
+ /**
+ * @brief Q7 vector multiplication.
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ */
+ void arm_mult_q7(
+ q7_t * pSrcA,
+ q7_t * pSrcB,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Q15 vector multiplication.
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ */
+ void arm_mult_q15(
+ q15_t * pSrcA,
+ q15_t * pSrcB,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Q31 vector multiplication.
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ */
+ void arm_mult_q31(
+ q31_t * pSrcA,
+ q31_t * pSrcB,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Floating-point vector multiplication.
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ */
+ void arm_mult_f32(
+ float32_t * pSrcA,
+ float32_t * pSrcB,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Instance structure for the Q15 CFFT/CIFFT function.
+ */
+ typedef struct
+ {
+ uint16_t fftLen; /**< length of the FFT. */
+ uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+ uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+ q15_t *pTwiddle; /**< points to the Sin twiddle factor table. */
+ uint16_t *pBitRevTable; /**< points to the bit reversal table. */
+ uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+ uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+ } arm_cfft_radix2_instance_q15;
+
+/* Deprecated */
+ arm_status arm_cfft_radix2_init_q15(
+ arm_cfft_radix2_instance_q15 * S,
+ uint16_t fftLen,
+ uint8_t ifftFlag,
+ uint8_t bitReverseFlag);
+
+/* Deprecated */
+ void arm_cfft_radix2_q15(
+ const arm_cfft_radix2_instance_q15 * S,
+ q15_t * pSrc);
+
+
+ /**
+ * @brief Instance structure for the Q15 CFFT/CIFFT function.
+ */
+ typedef struct
+ {
+ uint16_t fftLen; /**< length of the FFT. */
+ uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+ uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+ q15_t *pTwiddle; /**< points to the twiddle factor table. */
+ uint16_t *pBitRevTable; /**< points to the bit reversal table. */
+ uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+ uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+ } arm_cfft_radix4_instance_q15;
+
+/* Deprecated */
+ arm_status arm_cfft_radix4_init_q15(
+ arm_cfft_radix4_instance_q15 * S,
+ uint16_t fftLen,
+ uint8_t ifftFlag,
+ uint8_t bitReverseFlag);
+
+/* Deprecated */
+ void arm_cfft_radix4_q15(
+ const arm_cfft_radix4_instance_q15 * S,
+ q15_t * pSrc);
+
+ /**
+ * @brief Instance structure for the Radix-2 Q31 CFFT/CIFFT function.
+ */
+ typedef struct
+ {
+ uint16_t fftLen; /**< length of the FFT. */
+ uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+ uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+ q31_t *pTwiddle; /**< points to the Twiddle factor table. */
+ uint16_t *pBitRevTable; /**< points to the bit reversal table. */
+ uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+ uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+ } arm_cfft_radix2_instance_q31;
+
+/* Deprecated */
+ arm_status arm_cfft_radix2_init_q31(
+ arm_cfft_radix2_instance_q31 * S,
+ uint16_t fftLen,
+ uint8_t ifftFlag,
+ uint8_t bitReverseFlag);
+
+/* Deprecated */
+ void arm_cfft_radix2_q31(
+ const arm_cfft_radix2_instance_q31 * S,
+ q31_t * pSrc);
+
+ /**
+ * @brief Instance structure for the Q31 CFFT/CIFFT function.
+ */
+ typedef struct
+ {
+ uint16_t fftLen; /**< length of the FFT. */
+ uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+ uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+ q31_t *pTwiddle; /**< points to the twiddle factor table. */
+ uint16_t *pBitRevTable; /**< points to the bit reversal table. */
+ uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+ uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+ } arm_cfft_radix4_instance_q31;
+
+/* Deprecated */
+ void arm_cfft_radix4_q31(
+ const arm_cfft_radix4_instance_q31 * S,
+ q31_t * pSrc);
+
+/* Deprecated */
+ arm_status arm_cfft_radix4_init_q31(
+ arm_cfft_radix4_instance_q31 * S,
+ uint16_t fftLen,
+ uint8_t ifftFlag,
+ uint8_t bitReverseFlag);
+
+ /**
+ * @brief Instance structure for the floating-point CFFT/CIFFT function.
+ */
+ typedef struct
+ {
+ uint16_t fftLen; /**< length of the FFT. */
+ uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+ uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+ float32_t *pTwiddle; /**< points to the Twiddle factor table. */
+ uint16_t *pBitRevTable; /**< points to the bit reversal table. */
+ uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+ uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+ float32_t onebyfftLen; /**< value of 1/fftLen. */
+ } arm_cfft_radix2_instance_f32;
+
+/* Deprecated */
+ arm_status arm_cfft_radix2_init_f32(
+ arm_cfft_radix2_instance_f32 * S,
+ uint16_t fftLen,
+ uint8_t ifftFlag,
+ uint8_t bitReverseFlag);
+
+/* Deprecated */
+ void arm_cfft_radix2_f32(
+ const arm_cfft_radix2_instance_f32 * S,
+ float32_t * pSrc);
+
+ /**
+ * @brief Instance structure for the floating-point CFFT/CIFFT function.
+ */
+ typedef struct
+ {
+ uint16_t fftLen; /**< length of the FFT. */
+ uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+ uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+ float32_t *pTwiddle; /**< points to the Twiddle factor table. */
+ uint16_t *pBitRevTable; /**< points to the bit reversal table. */
+ uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+ uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+ float32_t onebyfftLen; /**< value of 1/fftLen. */
+ } arm_cfft_radix4_instance_f32;
+
+/* Deprecated */
+ arm_status arm_cfft_radix4_init_f32(
+ arm_cfft_radix4_instance_f32 * S,
+ uint16_t fftLen,
+ uint8_t ifftFlag,
+ uint8_t bitReverseFlag);
+
+/* Deprecated */
+ void arm_cfft_radix4_f32(
+ const arm_cfft_radix4_instance_f32 * S,
+ float32_t * pSrc);
+
+ /**
+ * @brief Instance structure for the fixed-point CFFT/CIFFT function.
+ */
+ typedef struct
+ {
+ uint16_t fftLen; /**< length of the FFT. */
+ const q15_t *pTwiddle; /**< points to the Twiddle factor table. */
+ const uint16_t *pBitRevTable; /**< points to the bit reversal table. */
+ uint16_t bitRevLength; /**< bit reversal table length. */
+ } arm_cfft_instance_q15;
+
+void arm_cfft_q15(
+ const arm_cfft_instance_q15 * S,
+ q15_t * p1,
+ uint8_t ifftFlag,
+ uint8_t bitReverseFlag);
+
+ /**
+ * @brief Instance structure for the fixed-point CFFT/CIFFT function.
+ */
+ typedef struct
+ {
+ uint16_t fftLen; /**< length of the FFT. */
+ const q31_t *pTwiddle; /**< points to the Twiddle factor table. */
+ const uint16_t *pBitRevTable; /**< points to the bit reversal table. */
+ uint16_t bitRevLength; /**< bit reversal table length. */
+ } arm_cfft_instance_q31;
+
+void arm_cfft_q31(
+ const arm_cfft_instance_q31 * S,
+ q31_t * p1,
+ uint8_t ifftFlag,
+ uint8_t bitReverseFlag);
+
+ /**
+ * @brief Instance structure for the floating-point CFFT/CIFFT function.
+ */
+ typedef struct
+ {
+ uint16_t fftLen; /**< length of the FFT. */
+ const float32_t *pTwiddle; /**< points to the Twiddle factor table. */
+ const uint16_t *pBitRevTable; /**< points to the bit reversal table. */
+ uint16_t bitRevLength; /**< bit reversal table length. */
+ } arm_cfft_instance_f32;
+
+ void arm_cfft_f32(
+ const arm_cfft_instance_f32 * S,
+ float32_t * p1,
+ uint8_t ifftFlag,
+ uint8_t bitReverseFlag);
+
+ /**
+ * @brief Instance structure for the Q15 RFFT/RIFFT function.
+ */
+ typedef struct
+ {
+ uint32_t fftLenReal; /**< length of the real FFT. */
+ uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */
+ uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */
+ uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+ q15_t *pTwiddleAReal; /**< points to the real twiddle factor table. */
+ q15_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */
+ const arm_cfft_instance_q15 *pCfft; /**< points to the complex FFT instance. */
+ } arm_rfft_instance_q15;
+
+ arm_status arm_rfft_init_q15(
+ arm_rfft_instance_q15 * S,
+ uint32_t fftLenReal,
+ uint32_t ifftFlagR,
+ uint32_t bitReverseFlag);
+
+ void arm_rfft_q15(
+ const arm_rfft_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst);
+
+ /**
+ * @brief Instance structure for the Q31 RFFT/RIFFT function.
+ */
+ typedef struct
+ {
+ uint32_t fftLenReal; /**< length of the real FFT. */
+ uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */
+ uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */
+ uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+ q31_t *pTwiddleAReal; /**< points to the real twiddle factor table. */
+ q31_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */
+ const arm_cfft_instance_q31 *pCfft; /**< points to the complex FFT instance. */
+ } arm_rfft_instance_q31;
+
+ arm_status arm_rfft_init_q31(
+ arm_rfft_instance_q31 * S,
+ uint32_t fftLenReal,
+ uint32_t ifftFlagR,
+ uint32_t bitReverseFlag);
+
+ void arm_rfft_q31(
+ const arm_rfft_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst);
+
+ /**
+ * @brief Instance structure for the floating-point RFFT/RIFFT function.
+ */
+ typedef struct
+ {
+ uint32_t fftLenReal; /**< length of the real FFT. */
+ uint16_t fftLenBy2; /**< length of the complex FFT. */
+ uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */
+ uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */
+ uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+ float32_t *pTwiddleAReal; /**< points to the real twiddle factor table. */
+ float32_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */
+ arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */
+ } arm_rfft_instance_f32;
+
+ arm_status arm_rfft_init_f32(
+ arm_rfft_instance_f32 * S,
+ arm_cfft_radix4_instance_f32 * S_CFFT,
+ uint32_t fftLenReal,
+ uint32_t ifftFlagR,
+ uint32_t bitReverseFlag);
+
+ void arm_rfft_f32(
+ const arm_rfft_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pDst);
+
+ /**
+ * @brief Instance structure for the floating-point RFFT/RIFFT function.
+ */
+typedef struct
+ {
+ arm_cfft_instance_f32 Sint; /**< Internal CFFT structure. */
+ uint16_t fftLenRFFT; /**< length of the real sequence */
+ float32_t * pTwiddleRFFT; /**< Twiddle factors real stage */
+ } arm_rfft_fast_instance_f32 ;
+
+arm_status arm_rfft_fast_init_f32 (
+ arm_rfft_fast_instance_f32 * S,
+ uint16_t fftLen);
+
+void arm_rfft_fast_f32(
+ arm_rfft_fast_instance_f32 * S,
+ float32_t * p, float32_t * pOut,
+ uint8_t ifftFlag);
+
+ /**
+ * @brief Instance structure for the floating-point DCT4/IDCT4 function.
+ */
+ typedef struct
+ {
+ uint16_t N; /**< length of the DCT4. */
+ uint16_t Nby2; /**< half of the length of the DCT4. */
+ float32_t normalize; /**< normalizing factor. */
+ float32_t *pTwiddle; /**< points to the twiddle factor table. */
+ float32_t *pCosFactor; /**< points to the cosFactor table. */
+ arm_rfft_instance_f32 *pRfft; /**< points to the real FFT instance. */
+ arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */
+ } arm_dct4_instance_f32;
+
+
+ /**
+ * @brief Initialization function for the floating-point DCT4/IDCT4.
+ * @param[in,out] S points to an instance of floating-point DCT4/IDCT4 structure.
+ * @param[in] S_RFFT points to an instance of floating-point RFFT/RIFFT structure.
+ * @param[in] S_CFFT points to an instance of floating-point CFFT/CIFFT structure.
+ * @param[in] N length of the DCT4.
+ * @param[in] Nby2 half of the length of the DCT4.
+ * @param[in] normalize normalizing factor.
+ * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal
is not a supported transform length.
+ */
+ arm_status arm_dct4_init_f32(
+ arm_dct4_instance_f32 * S,
+ arm_rfft_instance_f32 * S_RFFT,
+ arm_cfft_radix4_instance_f32 * S_CFFT,
+ uint16_t N,
+ uint16_t Nby2,
+ float32_t normalize);
+
+
+ /**
+ * @brief Processing function for the floating-point DCT4/IDCT4.
+ * @param[in] S points to an instance of the floating-point DCT4/IDCT4 structure.
+ * @param[in] pState points to state buffer.
+ * @param[in,out] pInlineBuffer points to the in-place input and output buffer.
+ */
+ void arm_dct4_f32(
+ const arm_dct4_instance_f32 * S,
+ float32_t * pState,
+ float32_t * pInlineBuffer);
+
+
+ /**
+ * @brief Instance structure for the Q31 DCT4/IDCT4 function.
+ */
+ typedef struct
+ {
+ uint16_t N; /**< length of the DCT4. */
+ uint16_t Nby2; /**< half of the length of the DCT4. */
+ q31_t normalize; /**< normalizing factor. */
+ q31_t *pTwiddle; /**< points to the twiddle factor table. */
+ q31_t *pCosFactor; /**< points to the cosFactor table. */
+ arm_rfft_instance_q31 *pRfft; /**< points to the real FFT instance. */
+ arm_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */
+ } arm_dct4_instance_q31;
+
+
+ /**
+ * @brief Initialization function for the Q31 DCT4/IDCT4.
+ * @param[in,out] S points to an instance of Q31 DCT4/IDCT4 structure.
+ * @param[in] S_RFFT points to an instance of Q31 RFFT/RIFFT structure
+ * @param[in] S_CFFT points to an instance of Q31 CFFT/CIFFT structure
+ * @param[in] N length of the DCT4.
+ * @param[in] Nby2 half of the length of the DCT4.
+ * @param[in] normalize normalizing factor.
+ * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N
is not a supported transform length.
+ */
+ arm_status arm_dct4_init_q31(
+ arm_dct4_instance_q31 * S,
+ arm_rfft_instance_q31 * S_RFFT,
+ arm_cfft_radix4_instance_q31 * S_CFFT,
+ uint16_t N,
+ uint16_t Nby2,
+ q31_t normalize);
+
+
+ /**
+ * @brief Processing function for the Q31 DCT4/IDCT4.
+ * @param[in] S points to an instance of the Q31 DCT4 structure.
+ * @param[in] pState points to state buffer.
+ * @param[in,out] pInlineBuffer points to the in-place input and output buffer.
+ */
+ void arm_dct4_q31(
+ const arm_dct4_instance_q31 * S,
+ q31_t * pState,
+ q31_t * pInlineBuffer);
+
+
+ /**
+ * @brief Instance structure for the Q15 DCT4/IDCT4 function.
+ */
+ typedef struct
+ {
+ uint16_t N; /**< length of the DCT4. */
+ uint16_t Nby2; /**< half of the length of the DCT4. */
+ q15_t normalize; /**< normalizing factor. */
+ q15_t *pTwiddle; /**< points to the twiddle factor table. */
+ q15_t *pCosFactor; /**< points to the cosFactor table. */
+ arm_rfft_instance_q15 *pRfft; /**< points to the real FFT instance. */
+ arm_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */
+ } arm_dct4_instance_q15;
+
+
+ /**
+ * @brief Initialization function for the Q15 DCT4/IDCT4.
+ * @param[in,out] S points to an instance of Q15 DCT4/IDCT4 structure.
+ * @param[in] S_RFFT points to an instance of Q15 RFFT/RIFFT structure.
+ * @param[in] S_CFFT points to an instance of Q15 CFFT/CIFFT structure.
+ * @param[in] N length of the DCT4.
+ * @param[in] Nby2 half of the length of the DCT4.
+ * @param[in] normalize normalizing factor.
+ * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N
is not a supported transform length.
+ */
+ arm_status arm_dct4_init_q15(
+ arm_dct4_instance_q15 * S,
+ arm_rfft_instance_q15 * S_RFFT,
+ arm_cfft_radix4_instance_q15 * S_CFFT,
+ uint16_t N,
+ uint16_t Nby2,
+ q15_t normalize);
+
+
+ /**
+ * @brief Processing function for the Q15 DCT4/IDCT4.
+ * @param[in] S points to an instance of the Q15 DCT4 structure.
+ * @param[in] pState points to state buffer.
+ * @param[in,out] pInlineBuffer points to the in-place input and output buffer.
+ */
+ void arm_dct4_q15(
+ const arm_dct4_instance_q15 * S,
+ q15_t * pState,
+ q15_t * pInlineBuffer);
+
+
+ /**
+ * @brief Floating-point vector addition.
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ */
+ void arm_add_f32(
+ float32_t * pSrcA,
+ float32_t * pSrcB,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Q7 vector addition.
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ */
+ void arm_add_q7(
+ q7_t * pSrcA,
+ q7_t * pSrcB,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Q15 vector addition.
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ */
+ void arm_add_q15(
+ q15_t * pSrcA,
+ q15_t * pSrcB,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Q31 vector addition.
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ */
+ void arm_add_q31(
+ q31_t * pSrcA,
+ q31_t * pSrcB,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Floating-point vector subtraction.
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ */
+ void arm_sub_f32(
+ float32_t * pSrcA,
+ float32_t * pSrcB,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Q7 vector subtraction.
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ */
+ void arm_sub_q7(
+ q7_t * pSrcA,
+ q7_t * pSrcB,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Q15 vector subtraction.
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ */
+ void arm_sub_q15(
+ q15_t * pSrcA,
+ q15_t * pSrcB,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Q31 vector subtraction.
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ */
+ void arm_sub_q31(
+ q31_t * pSrcA,
+ q31_t * pSrcB,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Multiplies a floating-point vector by a scalar.
+ * @param[in] pSrc points to the input vector
+ * @param[in] scale scale factor to be applied
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ */
+ void arm_scale_f32(
+ float32_t * pSrc,
+ float32_t scale,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Multiplies a Q7 vector by a scalar.
+ * @param[in] pSrc points to the input vector
+ * @param[in] scaleFract fractional portion of the scale value
+ * @param[in] shift number of bits to shift the result by
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ */
+ void arm_scale_q7(
+ q7_t * pSrc,
+ q7_t scaleFract,
+ int8_t shift,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Multiplies a Q15 vector by a scalar.
+ * @param[in] pSrc points to the input vector
+ * @param[in] scaleFract fractional portion of the scale value
+ * @param[in] shift number of bits to shift the result by
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ */
+ void arm_scale_q15(
+ q15_t * pSrc,
+ q15_t scaleFract,
+ int8_t shift,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Multiplies a Q31 vector by a scalar.
+ * @param[in] pSrc points to the input vector
+ * @param[in] scaleFract fractional portion of the scale value
+ * @param[in] shift number of bits to shift the result by
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ */
+ void arm_scale_q31(
+ q31_t * pSrc,
+ q31_t scaleFract,
+ int8_t shift,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Q7 vector absolute value.
+ * @param[in] pSrc points to the input buffer
+ * @param[out] pDst points to the output buffer
+ * @param[in] blockSize number of samples in each vector
+ */
+ void arm_abs_q7(
+ q7_t * pSrc,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Floating-point vector absolute value.
+ * @param[in] pSrc points to the input buffer
+ * @param[out] pDst points to the output buffer
+ * @param[in] blockSize number of samples in each vector
+ */
+ void arm_abs_f32(
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Q15 vector absolute value.
+ * @param[in] pSrc points to the input buffer
+ * @param[out] pDst points to the output buffer
+ * @param[in] blockSize number of samples in each vector
+ */
+ void arm_abs_q15(
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Q31 vector absolute value.
+ * @param[in] pSrc points to the input buffer
+ * @param[out] pDst points to the output buffer
+ * @param[in] blockSize number of samples in each vector
+ */
+ void arm_abs_q31(
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Dot product of floating-point vectors.
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[in] blockSize number of samples in each vector
+ * @param[out] result output result returned here
+ */
+ void arm_dot_prod_f32(
+ float32_t * pSrcA,
+ float32_t * pSrcB,
+ uint32_t blockSize,
+ float32_t * result);
+
+
+ /**
+ * @brief Dot product of Q7 vectors.
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[in] blockSize number of samples in each vector
+ * @param[out] result output result returned here
+ */
+ void arm_dot_prod_q7(
+ q7_t * pSrcA,
+ q7_t * pSrcB,
+ uint32_t blockSize,
+ q31_t * result);
+
+
+ /**
+ * @brief Dot product of Q15 vectors.
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[in] blockSize number of samples in each vector
+ * @param[out] result output result returned here
+ */
+ void arm_dot_prod_q15(
+ q15_t * pSrcA,
+ q15_t * pSrcB,
+ uint32_t blockSize,
+ q63_t * result);
+
+
+ /**
+ * @brief Dot product of Q31 vectors.
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[in] blockSize number of samples in each vector
+ * @param[out] result output result returned here
+ */
+ void arm_dot_prod_q31(
+ q31_t * pSrcA,
+ q31_t * pSrcB,
+ uint32_t blockSize,
+ q63_t * result);
+
+
+ /**
+ * @brief Shifts the elements of a Q7 vector a specified number of bits.
+ * @param[in] pSrc points to the input vector
+ * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right.
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ */
+ void arm_shift_q7(
+ q7_t * pSrc,
+ int8_t shiftBits,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Shifts the elements of a Q15 vector a specified number of bits.
+ * @param[in] pSrc points to the input vector
+ * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right.
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ */
+ void arm_shift_q15(
+ q15_t * pSrc,
+ int8_t shiftBits,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Shifts the elements of a Q31 vector a specified number of bits.
+ * @param[in] pSrc points to the input vector
+ * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right.
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ */
+ void arm_shift_q31(
+ q31_t * pSrc,
+ int8_t shiftBits,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Adds a constant offset to a floating-point vector.
+ * @param[in] pSrc points to the input vector
+ * @param[in] offset is the offset to be added
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ */
+ void arm_offset_f32(
+ float32_t * pSrc,
+ float32_t offset,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Adds a constant offset to a Q7 vector.
+ * @param[in] pSrc points to the input vector
+ * @param[in] offset is the offset to be added
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ */
+ void arm_offset_q7(
+ q7_t * pSrc,
+ q7_t offset,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Adds a constant offset to a Q15 vector.
+ * @param[in] pSrc points to the input vector
+ * @param[in] offset is the offset to be added
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ */
+ void arm_offset_q15(
+ q15_t * pSrc,
+ q15_t offset,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Adds a constant offset to a Q31 vector.
+ * @param[in] pSrc points to the input vector
+ * @param[in] offset is the offset to be added
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ */
+ void arm_offset_q31(
+ q31_t * pSrc,
+ q31_t offset,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Negates the elements of a floating-point vector.
+ * @param[in] pSrc points to the input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ */
+ void arm_negate_f32(
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Negates the elements of a Q7 vector.
+ * @param[in] pSrc points to the input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ */
+ void arm_negate_q7(
+ q7_t * pSrc,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Negates the elements of a Q15 vector.
+ * @param[in] pSrc points to the input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ */
+ void arm_negate_q15(
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Negates the elements of a Q31 vector.
+ * @param[in] pSrc points to the input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ */
+ void arm_negate_q31(
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Copies the elements of a floating-point vector.
+ * @param[in] pSrc input pointer
+ * @param[out] pDst output pointer
+ * @param[in] blockSize number of samples to process
+ */
+ void arm_copy_f32(
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Copies the elements of a Q7 vector.
+ * @param[in] pSrc input pointer
+ * @param[out] pDst output pointer
+ * @param[in] blockSize number of samples to process
+ */
+ void arm_copy_q7(
+ q7_t * pSrc,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Copies the elements of a Q15 vector.
+ * @param[in] pSrc input pointer
+ * @param[out] pDst output pointer
+ * @param[in] blockSize number of samples to process
+ */
+ void arm_copy_q15(
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Copies the elements of a Q31 vector.
+ * @param[in] pSrc input pointer
+ * @param[out] pDst output pointer
+ * @param[in] blockSize number of samples to process
+ */
+ void arm_copy_q31(
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Fills a constant value into a floating-point vector.
+ * @param[in] value input value to be filled
+ * @param[out] pDst output pointer
+ * @param[in] blockSize number of samples to process
+ */
+ void arm_fill_f32(
+ float32_t value,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Fills a constant value into a Q7 vector.
+ * @param[in] value input value to be filled
+ * @param[out] pDst output pointer
+ * @param[in] blockSize number of samples to process
+ */
+ void arm_fill_q7(
+ q7_t value,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Fills a constant value into a Q15 vector.
+ * @param[in] value input value to be filled
+ * @param[out] pDst output pointer
+ * @param[in] blockSize number of samples to process
+ */
+ void arm_fill_q15(
+ q15_t value,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Fills a constant value into a Q31 vector.
+ * @param[in] value input value to be filled
+ * @param[out] pDst output pointer
+ * @param[in] blockSize number of samples to process
+ */
+ void arm_fill_q31(
+ q31_t value,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+/**
+ * @brief Convolution of floating-point sequences.
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the location where the output result is written. Length srcALen+srcBLen-1.
+ */
+ void arm_conv_f32(
+ float32_t * pSrcA,
+ uint32_t srcALen,
+ float32_t * pSrcB,
+ uint32_t srcBLen,
+ float32_t * pDst);
+
+
+ /**
+ * @brief Convolution of Q15 sequences.
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1.
+ * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+ * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen).
+ */
+ void arm_conv_opt_q15(
+ q15_t * pSrcA,
+ uint32_t srcALen,
+ q15_t * pSrcB,
+ uint32_t srcBLen,
+ q15_t * pDst,
+ q15_t * pScratch1,
+ q15_t * pScratch2);
+
+
+/**
+ * @brief Convolution of Q15 sequences.
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the location where the output result is written. Length srcALen+srcBLen-1.
+ */
+ void arm_conv_q15(
+ q15_t * pSrcA,
+ uint32_t srcALen,
+ q15_t * pSrcB,
+ uint32_t srcBLen,
+ q15_t * pDst);
+
+
+ /**
+ * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1.
+ */
+ void arm_conv_fast_q15(
+ q15_t * pSrcA,
+ uint32_t srcALen,
+ q15_t * pSrcB,
+ uint32_t srcBLen,
+ q15_t * pDst);
+
+
+ /**
+ * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1.
+ * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+ * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen).
+ */
+ void arm_conv_fast_opt_q15(
+ q15_t * pSrcA,
+ uint32_t srcALen,
+ q15_t * pSrcB,
+ uint32_t srcBLen,
+ q15_t * pDst,
+ q15_t * pScratch1,
+ q15_t * pScratch2);
+
+
+ /**
+ * @brief Convolution of Q31 sequences.
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1.
+ */
+ void arm_conv_q31(
+ q31_t * pSrcA,
+ uint32_t srcALen,
+ q31_t * pSrcB,
+ uint32_t srcBLen,
+ q31_t * pDst);
+
+
+ /**
+ * @brief Convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1.
+ */
+ void arm_conv_fast_q31(
+ q31_t * pSrcA,
+ uint32_t srcALen,
+ q31_t * pSrcB,
+ uint32_t srcBLen,
+ q31_t * pDst);
+
+
+ /**
+ * @brief Convolution of Q7 sequences.
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1.
+ * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+ * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen).
+ */
+ void arm_conv_opt_q7(
+ q7_t * pSrcA,
+ uint32_t srcALen,
+ q7_t * pSrcB,
+ uint32_t srcBLen,
+ q7_t * pDst,
+ q15_t * pScratch1,
+ q15_t * pScratch2);
+
+
+ /**
+ * @brief Convolution of Q7 sequences.
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1.
+ */
+ void arm_conv_q7(
+ q7_t * pSrcA,
+ uint32_t srcALen,
+ q7_t * pSrcB,
+ uint32_t srcBLen,
+ q7_t * pDst);
+
+
+ /**
+ * @brief Partial convolution of floating-point sequences.
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data
+ * @param[in] firstIndex is the first output sample to start with.
+ * @param[in] numPoints is the number of output points to be computed.
+ * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+ */
+ arm_status arm_conv_partial_f32(
+ float32_t * pSrcA,
+ uint32_t srcALen,
+ float32_t * pSrcB,
+ uint32_t srcBLen,
+ float32_t * pDst,
+ uint32_t firstIndex,
+ uint32_t numPoints);
+
+
+ /**
+ * @brief Partial convolution of Q15 sequences.
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data
+ * @param[in] firstIndex is the first output sample to start with.
+ * @param[in] numPoints is the number of output points to be computed.
+ * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+ * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen).
+ * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+ */
+ arm_status arm_conv_partial_opt_q15(
+ q15_t * pSrcA,
+ uint32_t srcALen,
+ q15_t * pSrcB,
+ uint32_t srcBLen,
+ q15_t * pDst,
+ uint32_t firstIndex,
+ uint32_t numPoints,
+ q15_t * pScratch1,
+ q15_t * pScratch2);
+
+
+ /**
+ * @brief Partial convolution of Q15 sequences.
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data
+ * @param[in] firstIndex is the first output sample to start with.
+ * @param[in] numPoints is the number of output points to be computed.
+ * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+ */
+ arm_status arm_conv_partial_q15(
+ q15_t * pSrcA,
+ uint32_t srcALen,
+ q15_t * pSrcB,
+ uint32_t srcBLen,
+ q15_t * pDst,
+ uint32_t firstIndex,
+ uint32_t numPoints);
+
+
+ /**
+ * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data
+ * @param[in] firstIndex is the first output sample to start with.
+ * @param[in] numPoints is the number of output points to be computed.
+ * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+ */
+ arm_status arm_conv_partial_fast_q15(
+ q15_t * pSrcA,
+ uint32_t srcALen,
+ q15_t * pSrcB,
+ uint32_t srcBLen,
+ q15_t * pDst,
+ uint32_t firstIndex,
+ uint32_t numPoints);
+
+
+ /**
+ * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data
+ * @param[in] firstIndex is the first output sample to start with.
+ * @param[in] numPoints is the number of output points to be computed.
+ * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+ * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen).
+ * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+ */
+ arm_status arm_conv_partial_fast_opt_q15(
+ q15_t * pSrcA,
+ uint32_t srcALen,
+ q15_t * pSrcB,
+ uint32_t srcBLen,
+ q15_t * pDst,
+ uint32_t firstIndex,
+ uint32_t numPoints,
+ q15_t * pScratch1,
+ q15_t * pScratch2);
+
+
+ /**
+ * @brief Partial convolution of Q31 sequences.
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data
+ * @param[in] firstIndex is the first output sample to start with.
+ * @param[in] numPoints is the number of output points to be computed.
+ * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+ */
+ arm_status arm_conv_partial_q31(
+ q31_t * pSrcA,
+ uint32_t srcALen,
+ q31_t * pSrcB,
+ uint32_t srcBLen,
+ q31_t * pDst,
+ uint32_t firstIndex,
+ uint32_t numPoints);
+
+
+ /**
+ * @brief Partial convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data
+ * @param[in] firstIndex is the first output sample to start with.
+ * @param[in] numPoints is the number of output points to be computed.
+ * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+ */
+ arm_status arm_conv_partial_fast_q31(
+ q31_t * pSrcA,
+ uint32_t srcALen,
+ q31_t * pSrcB,
+ uint32_t srcBLen,
+ q31_t * pDst,
+ uint32_t firstIndex,
+ uint32_t numPoints);
+
+
+ /**
+ * @brief Partial convolution of Q7 sequences
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data
+ * @param[in] firstIndex is the first output sample to start with.
+ * @param[in] numPoints is the number of output points to be computed.
+ * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+ * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen).
+ * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+ */
+ arm_status arm_conv_partial_opt_q7(
+ q7_t * pSrcA,
+ uint32_t srcALen,
+ q7_t * pSrcB,
+ uint32_t srcBLen,
+ q7_t * pDst,
+ uint32_t firstIndex,
+ uint32_t numPoints,
+ q15_t * pScratch1,
+ q15_t * pScratch2);
+
+
+/**
+ * @brief Partial convolution of Q7 sequences.
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data
+ * @param[in] firstIndex is the first output sample to start with.
+ * @param[in] numPoints is the number of output points to be computed.
+ * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+ */
+ arm_status arm_conv_partial_q7(
+ q7_t * pSrcA,
+ uint32_t srcALen,
+ q7_t * pSrcB,
+ uint32_t srcBLen,
+ q7_t * pDst,
+ uint32_t firstIndex,
+ uint32_t numPoints);
+
+
+ /**
+ * @brief Instance structure for the Q15 FIR decimator.
+ */
+ typedef struct
+ {
+ uint8_t M; /**< decimation factor. */
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/
+ q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+ } arm_fir_decimate_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q31 FIR decimator.
+ */
+ typedef struct
+ {
+ uint8_t M; /**< decimation factor. */
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/
+ q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+ } arm_fir_decimate_instance_q31;
+
+ /**
+ * @brief Instance structure for the floating-point FIR decimator.
+ */
+ typedef struct
+ {
+ uint8_t M; /**< decimation factor. */
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/
+ float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+ } arm_fir_decimate_instance_f32;
+
+
+ /**
+ * @brief Processing function for the floating-point FIR decimator.
+ * @param[in] S points to an instance of the floating-point FIR decimator structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data
+ * @param[in] blockSize number of input samples to process per call.
+ */
+ void arm_fir_decimate_f32(
+ const arm_fir_decimate_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the floating-point FIR decimator.
+ * @param[in,out] S points to an instance of the floating-point FIR decimator structure.
+ * @param[in] numTaps number of coefficients in the filter.
+ * @param[in] M decimation factor.
+ * @param[in] pCoeffs points to the filter coefficients.
+ * @param[in] pState points to the state buffer.
+ * @param[in] blockSize number of input samples to process per call.
+ * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+ * blockSize
is not a multiple of M
.
+ */
+ arm_status arm_fir_decimate_init_f32(
+ arm_fir_decimate_instance_f32 * S,
+ uint16_t numTaps,
+ uint8_t M,
+ float32_t * pCoeffs,
+ float32_t * pState,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the Q15 FIR decimator.
+ * @param[in] S points to an instance of the Q15 FIR decimator structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data
+ * @param[in] blockSize number of input samples to process per call.
+ */
+ void arm_fir_decimate_q15(
+ const arm_fir_decimate_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the Q15 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4.
+ * @param[in] S points to an instance of the Q15 FIR decimator structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data
+ * @param[in] blockSize number of input samples to process per call.
+ */
+ void arm_fir_decimate_fast_q15(
+ const arm_fir_decimate_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the Q15 FIR decimator.
+ * @param[in,out] S points to an instance of the Q15 FIR decimator structure.
+ * @param[in] numTaps number of coefficients in the filter.
+ * @param[in] M decimation factor.
+ * @param[in] pCoeffs points to the filter coefficients.
+ * @param[in] pState points to the state buffer.
+ * @param[in] blockSize number of input samples to process per call.
+ * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+ * blockSize
is not a multiple of M
.
+ */
+ arm_status arm_fir_decimate_init_q15(
+ arm_fir_decimate_instance_q15 * S,
+ uint16_t numTaps,
+ uint8_t M,
+ q15_t * pCoeffs,
+ q15_t * pState,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the Q31 FIR decimator.
+ * @param[in] S points to an instance of the Q31 FIR decimator structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data
+ * @param[in] blockSize number of input samples to process per call.
+ */
+ void arm_fir_decimate_q31(
+ const arm_fir_decimate_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Processing function for the Q31 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4.
+ * @param[in] S points to an instance of the Q31 FIR decimator structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data
+ * @param[in] blockSize number of input samples to process per call.
+ */
+ void arm_fir_decimate_fast_q31(
+ arm_fir_decimate_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the Q31 FIR decimator.
+ * @param[in,out] S points to an instance of the Q31 FIR decimator structure.
+ * @param[in] numTaps number of coefficients in the filter.
+ * @param[in] M decimation factor.
+ * @param[in] pCoeffs points to the filter coefficients.
+ * @param[in] pState points to the state buffer.
+ * @param[in] blockSize number of input samples to process per call.
+ * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+ * blockSize
is not a multiple of M
.
+ */
+ arm_status arm_fir_decimate_init_q31(
+ arm_fir_decimate_instance_q31 * S,
+ uint16_t numTaps,
+ uint8_t M,
+ q31_t * pCoeffs,
+ q31_t * pState,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Instance structure for the Q15 FIR interpolator.
+ */
+ typedef struct
+ {
+ uint8_t L; /**< upsample factor. */
+ uint16_t phaseLength; /**< length of each polyphase filter component. */
+ q15_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */
+ q15_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */
+ } arm_fir_interpolate_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q31 FIR interpolator.
+ */
+ typedef struct
+ {
+ uint8_t L; /**< upsample factor. */
+ uint16_t phaseLength; /**< length of each polyphase filter component. */
+ q31_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */
+ q31_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */
+ } arm_fir_interpolate_instance_q31;
+
+ /**
+ * @brief Instance structure for the floating-point FIR interpolator.
+ */
+ typedef struct
+ {
+ uint8_t L; /**< upsample factor. */
+ uint16_t phaseLength; /**< length of each polyphase filter component. */
+ float32_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */
+ float32_t *pState; /**< points to the state variable array. The array is of length phaseLength+numTaps-1. */
+ } arm_fir_interpolate_instance_f32;
+
+
+ /**
+ * @brief Processing function for the Q15 FIR interpolator.
+ * @param[in] S points to an instance of the Q15 FIR interpolator structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data.
+ * @param[in] blockSize number of input samples to process per call.
+ */
+ void arm_fir_interpolate_q15(
+ const arm_fir_interpolate_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the Q15 FIR interpolator.
+ * @param[in,out] S points to an instance of the Q15 FIR interpolator structure.
+ * @param[in] L upsample factor.
+ * @param[in] numTaps number of filter coefficients in the filter.
+ * @param[in] pCoeffs points to the filter coefficient buffer.
+ * @param[in] pState points to the state buffer.
+ * @param[in] blockSize number of input samples to process per call.
+ * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+ * the filter length numTaps
is not a multiple of the interpolation factor L
.
+ */
+ arm_status arm_fir_interpolate_init_q15(
+ arm_fir_interpolate_instance_q15 * S,
+ uint8_t L,
+ uint16_t numTaps,
+ q15_t * pCoeffs,
+ q15_t * pState,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the Q31 FIR interpolator.
+ * @param[in] S points to an instance of the Q15 FIR interpolator structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data.
+ * @param[in] blockSize number of input samples to process per call.
+ */
+ void arm_fir_interpolate_q31(
+ const arm_fir_interpolate_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the Q31 FIR interpolator.
+ * @param[in,out] S points to an instance of the Q31 FIR interpolator structure.
+ * @param[in] L upsample factor.
+ * @param[in] numTaps number of filter coefficients in the filter.
+ * @param[in] pCoeffs points to the filter coefficient buffer.
+ * @param[in] pState points to the state buffer.
+ * @param[in] blockSize number of input samples to process per call.
+ * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+ * the filter length numTaps
is not a multiple of the interpolation factor L
.
+ */
+ arm_status arm_fir_interpolate_init_q31(
+ arm_fir_interpolate_instance_q31 * S,
+ uint8_t L,
+ uint16_t numTaps,
+ q31_t * pCoeffs,
+ q31_t * pState,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the floating-point FIR interpolator.
+ * @param[in] S points to an instance of the floating-point FIR interpolator structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data.
+ * @param[in] blockSize number of input samples to process per call.
+ */
+ void arm_fir_interpolate_f32(
+ const arm_fir_interpolate_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the floating-point FIR interpolator.
+ * @param[in,out] S points to an instance of the floating-point FIR interpolator structure.
+ * @param[in] L upsample factor.
+ * @param[in] numTaps number of filter coefficients in the filter.
+ * @param[in] pCoeffs points to the filter coefficient buffer.
+ * @param[in] pState points to the state buffer.
+ * @param[in] blockSize number of input samples to process per call.
+ * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+ * the filter length numTaps
is not a multiple of the interpolation factor L
.
+ */
+ arm_status arm_fir_interpolate_init_f32(
+ arm_fir_interpolate_instance_f32 * S,
+ uint8_t L,
+ uint16_t numTaps,
+ float32_t * pCoeffs,
+ float32_t * pState,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Instance structure for the high precision Q31 Biquad cascade filter.
+ */
+ typedef struct
+ {
+ uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */
+ q63_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */
+ q31_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */
+ uint8_t postShift; /**< additional shift, in bits, applied to each output sample. */
+ } arm_biquad_cas_df1_32x64_ins_q31;
+
+
+ /**
+ * @param[in] S points to an instance of the high precision Q31 Biquad cascade filter structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_biquad_cas_df1_32x64_q31(
+ const arm_biquad_cas_df1_32x64_ins_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @param[in,out] S points to an instance of the high precision Q31 Biquad cascade filter structure.
+ * @param[in] numStages number of 2nd order stages in the filter.
+ * @param[in] pCoeffs points to the filter coefficients.
+ * @param[in] pState points to the state buffer.
+ * @param[in] postShift shift to be applied to the output. Varies according to the coefficients format
+ */
+ void arm_biquad_cas_df1_32x64_init_q31(
+ arm_biquad_cas_df1_32x64_ins_q31 * S,
+ uint8_t numStages,
+ q31_t * pCoeffs,
+ q63_t * pState,
+ uint8_t postShift);
+
+
+ /**
+ * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter.
+ */
+ typedef struct
+ {
+ uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */
+ float32_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */
+ float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */
+ } arm_biquad_cascade_df2T_instance_f32;
+
+ /**
+ * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter.
+ */
+ typedef struct
+ {
+ uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */
+ float32_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */
+ float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */
+ } arm_biquad_cascade_stereo_df2T_instance_f32;
+
+ /**
+ * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter.
+ */
+ typedef struct
+ {
+ uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */
+ float64_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */
+ float64_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */
+ } arm_biquad_cascade_df2T_instance_f64;
+
+
+ /**
+ * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter.
+ * @param[in] S points to an instance of the filter data structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_biquad_cascade_df2T_f32(
+ const arm_biquad_cascade_df2T_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. 2 channels
+ * @param[in] S points to an instance of the filter data structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_biquad_cascade_stereo_df2T_f32(
+ const arm_biquad_cascade_stereo_df2T_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter.
+ * @param[in] S points to an instance of the filter data structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_biquad_cascade_df2T_f64(
+ const arm_biquad_cascade_df2T_instance_f64 * S,
+ float64_t * pSrc,
+ float64_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter.
+ * @param[in,out] S points to an instance of the filter data structure.
+ * @param[in] numStages number of 2nd order stages in the filter.
+ * @param[in] pCoeffs points to the filter coefficients.
+ * @param[in] pState points to the state buffer.
+ */
+ void arm_biquad_cascade_df2T_init_f32(
+ arm_biquad_cascade_df2T_instance_f32 * S,
+ uint8_t numStages,
+ float32_t * pCoeffs,
+ float32_t * pState);
+
+
+ /**
+ * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter.
+ * @param[in,out] S points to an instance of the filter data structure.
+ * @param[in] numStages number of 2nd order stages in the filter.
+ * @param[in] pCoeffs points to the filter coefficients.
+ * @param[in] pState points to the state buffer.
+ */
+ void arm_biquad_cascade_stereo_df2T_init_f32(
+ arm_biquad_cascade_stereo_df2T_instance_f32 * S,
+ uint8_t numStages,
+ float32_t * pCoeffs,
+ float32_t * pState);
+
+
+ /**
+ * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter.
+ * @param[in,out] S points to an instance of the filter data structure.
+ * @param[in] numStages number of 2nd order stages in the filter.
+ * @param[in] pCoeffs points to the filter coefficients.
+ * @param[in] pState points to the state buffer.
+ */
+ void arm_biquad_cascade_df2T_init_f64(
+ arm_biquad_cascade_df2T_instance_f64 * S,
+ uint8_t numStages,
+ float64_t * pCoeffs,
+ float64_t * pState);
+
+
+ /**
+ * @brief Instance structure for the Q15 FIR lattice filter.
+ */
+ typedef struct
+ {
+ uint16_t numStages; /**< number of filter stages. */
+ q15_t *pState; /**< points to the state variable array. The array is of length numStages. */
+ q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */
+ } arm_fir_lattice_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q31 FIR lattice filter.
+ */
+ typedef struct
+ {
+ uint16_t numStages; /**< number of filter stages. */
+ q31_t *pState; /**< points to the state variable array. The array is of length numStages. */
+ q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */
+ } arm_fir_lattice_instance_q31;
+
+ /**
+ * @brief Instance structure for the floating-point FIR lattice filter.
+ */
+ typedef struct
+ {
+ uint16_t numStages; /**< number of filter stages. */
+ float32_t *pState; /**< points to the state variable array. The array is of length numStages. */
+ float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */
+ } arm_fir_lattice_instance_f32;
+
+
+ /**
+ * @brief Initialization function for the Q15 FIR lattice filter.
+ * @param[in] S points to an instance of the Q15 FIR lattice structure.
+ * @param[in] numStages number of filter stages.
+ * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages.
+ * @param[in] pState points to the state buffer. The array is of length numStages.
+ */
+ void arm_fir_lattice_init_q15(
+ arm_fir_lattice_instance_q15 * S,
+ uint16_t numStages,
+ q15_t * pCoeffs,
+ q15_t * pState);
+
+
+ /**
+ * @brief Processing function for the Q15 FIR lattice filter.
+ * @param[in] S points to an instance of the Q15 FIR lattice structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_fir_lattice_q15(
+ const arm_fir_lattice_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the Q31 FIR lattice filter.
+ * @param[in] S points to an instance of the Q31 FIR lattice structure.
+ * @param[in] numStages number of filter stages.
+ * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages.
+ * @param[in] pState points to the state buffer. The array is of length numStages.
+ */
+ void arm_fir_lattice_init_q31(
+ arm_fir_lattice_instance_q31 * S,
+ uint16_t numStages,
+ q31_t * pCoeffs,
+ q31_t * pState);
+
+
+ /**
+ * @brief Processing function for the Q31 FIR lattice filter.
+ * @param[in] S points to an instance of the Q31 FIR lattice structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_fir_lattice_q31(
+ const arm_fir_lattice_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+/**
+ * @brief Initialization function for the floating-point FIR lattice filter.
+ * @param[in] S points to an instance of the floating-point FIR lattice structure.
+ * @param[in] numStages number of filter stages.
+ * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages.
+ * @param[in] pState points to the state buffer. The array is of length numStages.
+ */
+ void arm_fir_lattice_init_f32(
+ arm_fir_lattice_instance_f32 * S,
+ uint16_t numStages,
+ float32_t * pCoeffs,
+ float32_t * pState);
+
+
+ /**
+ * @brief Processing function for the floating-point FIR lattice filter.
+ * @param[in] S points to an instance of the floating-point FIR lattice structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_fir_lattice_f32(
+ const arm_fir_lattice_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Instance structure for the Q15 IIR lattice filter.
+ */
+ typedef struct
+ {
+ uint16_t numStages; /**< number of stages in the filter. */
+ q15_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */
+ q15_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */
+ q15_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */
+ } arm_iir_lattice_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q31 IIR lattice filter.
+ */
+ typedef struct
+ {
+ uint16_t numStages; /**< number of stages in the filter. */
+ q31_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */
+ q31_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */
+ q31_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */
+ } arm_iir_lattice_instance_q31;
+
+ /**
+ * @brief Instance structure for the floating-point IIR lattice filter.
+ */
+ typedef struct
+ {
+ uint16_t numStages; /**< number of stages in the filter. */
+ float32_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */
+ float32_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */
+ float32_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */
+ } arm_iir_lattice_instance_f32;
+
+
+ /**
+ * @brief Processing function for the floating-point IIR lattice filter.
+ * @param[in] S points to an instance of the floating-point IIR lattice structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_iir_lattice_f32(
+ const arm_iir_lattice_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the floating-point IIR lattice filter.
+ * @param[in] S points to an instance of the floating-point IIR lattice structure.
+ * @param[in] numStages number of stages in the filter.
+ * @param[in] pkCoeffs points to the reflection coefficient buffer. The array is of length numStages.
+ * @param[in] pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1.
+ * @param[in] pState points to the state buffer. The array is of length numStages+blockSize-1.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_iir_lattice_init_f32(
+ arm_iir_lattice_instance_f32 * S,
+ uint16_t numStages,
+ float32_t * pkCoeffs,
+ float32_t * pvCoeffs,
+ float32_t * pState,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the Q31 IIR lattice filter.
+ * @param[in] S points to an instance of the Q31 IIR lattice structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_iir_lattice_q31(
+ const arm_iir_lattice_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the Q31 IIR lattice filter.
+ * @param[in] S points to an instance of the Q31 IIR lattice structure.
+ * @param[in] numStages number of stages in the filter.
+ * @param[in] pkCoeffs points to the reflection coefficient buffer. The array is of length numStages.
+ * @param[in] pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1.
+ * @param[in] pState points to the state buffer. The array is of length numStages+blockSize.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_iir_lattice_init_q31(
+ arm_iir_lattice_instance_q31 * S,
+ uint16_t numStages,
+ q31_t * pkCoeffs,
+ q31_t * pvCoeffs,
+ q31_t * pState,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the Q15 IIR lattice filter.
+ * @param[in] S points to an instance of the Q15 IIR lattice structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_iir_lattice_q15(
+ const arm_iir_lattice_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+/**
+ * @brief Initialization function for the Q15 IIR lattice filter.
+ * @param[in] S points to an instance of the fixed-point Q15 IIR lattice structure.
+ * @param[in] numStages number of stages in the filter.
+ * @param[in] pkCoeffs points to reflection coefficient buffer. The array is of length numStages.
+ * @param[in] pvCoeffs points to ladder coefficient buffer. The array is of length numStages+1.
+ * @param[in] pState points to state buffer. The array is of length numStages+blockSize.
+ * @param[in] blockSize number of samples to process per call.
+ */
+ void arm_iir_lattice_init_q15(
+ arm_iir_lattice_instance_q15 * S,
+ uint16_t numStages,
+ q15_t * pkCoeffs,
+ q15_t * pvCoeffs,
+ q15_t * pState,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Instance structure for the floating-point LMS filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+ float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */
+ float32_t mu; /**< step size that controls filter coefficient updates. */
+ } arm_lms_instance_f32;
+
+
+ /**
+ * @brief Processing function for floating-point LMS filter.
+ * @param[in] S points to an instance of the floating-point LMS filter structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[in] pRef points to the block of reference data.
+ * @param[out] pOut points to the block of output data.
+ * @param[out] pErr points to the block of error data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_lms_f32(
+ const arm_lms_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pRef,
+ float32_t * pOut,
+ float32_t * pErr,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for floating-point LMS filter.
+ * @param[in] S points to an instance of the floating-point LMS filter structure.
+ * @param[in] numTaps number of filter coefficients.
+ * @param[in] pCoeffs points to the coefficient buffer.
+ * @param[in] pState points to state buffer.
+ * @param[in] mu step size that controls filter coefficient updates.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_lms_init_f32(
+ arm_lms_instance_f32 * S,
+ uint16_t numTaps,
+ float32_t * pCoeffs,
+ float32_t * pState,
+ float32_t mu,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Instance structure for the Q15 LMS filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+ q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */
+ q15_t mu; /**< step size that controls filter coefficient updates. */
+ uint32_t postShift; /**< bit shift applied to coefficients. */
+ } arm_lms_instance_q15;
+
+
+ /**
+ * @brief Initialization function for the Q15 LMS filter.
+ * @param[in] S points to an instance of the Q15 LMS filter structure.
+ * @param[in] numTaps number of filter coefficients.
+ * @param[in] pCoeffs points to the coefficient buffer.
+ * @param[in] pState points to the state buffer.
+ * @param[in] mu step size that controls filter coefficient updates.
+ * @param[in] blockSize number of samples to process.
+ * @param[in] postShift bit shift applied to coefficients.
+ */
+ void arm_lms_init_q15(
+ arm_lms_instance_q15 * S,
+ uint16_t numTaps,
+ q15_t * pCoeffs,
+ q15_t * pState,
+ q15_t mu,
+ uint32_t blockSize,
+ uint32_t postShift);
+
+
+ /**
+ * @brief Processing function for Q15 LMS filter.
+ * @param[in] S points to an instance of the Q15 LMS filter structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[in] pRef points to the block of reference data.
+ * @param[out] pOut points to the block of output data.
+ * @param[out] pErr points to the block of error data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_lms_q15(
+ const arm_lms_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pRef,
+ q15_t * pOut,
+ q15_t * pErr,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Instance structure for the Q31 LMS filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+ q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */
+ q31_t mu; /**< step size that controls filter coefficient updates. */
+ uint32_t postShift; /**< bit shift applied to coefficients. */
+ } arm_lms_instance_q31;
+
+
+ /**
+ * @brief Processing function for Q31 LMS filter.
+ * @param[in] S points to an instance of the Q15 LMS filter structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[in] pRef points to the block of reference data.
+ * @param[out] pOut points to the block of output data.
+ * @param[out] pErr points to the block of error data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_lms_q31(
+ const arm_lms_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pRef,
+ q31_t * pOut,
+ q31_t * pErr,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for Q31 LMS filter.
+ * @param[in] S points to an instance of the Q31 LMS filter structure.
+ * @param[in] numTaps number of filter coefficients.
+ * @param[in] pCoeffs points to coefficient buffer.
+ * @param[in] pState points to state buffer.
+ * @param[in] mu step size that controls filter coefficient updates.
+ * @param[in] blockSize number of samples to process.
+ * @param[in] postShift bit shift applied to coefficients.
+ */
+ void arm_lms_init_q31(
+ arm_lms_instance_q31 * S,
+ uint16_t numTaps,
+ q31_t * pCoeffs,
+ q31_t * pState,
+ q31_t mu,
+ uint32_t blockSize,
+ uint32_t postShift);
+
+
+ /**
+ * @brief Instance structure for the floating-point normalized LMS filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+ float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */
+ float32_t mu; /**< step size that control filter coefficient updates. */
+ float32_t energy; /**< saves previous frame energy. */
+ float32_t x0; /**< saves previous input sample. */
+ } arm_lms_norm_instance_f32;
+
+
+ /**
+ * @brief Processing function for floating-point normalized LMS filter.
+ * @param[in] S points to an instance of the floating-point normalized LMS filter structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[in] pRef points to the block of reference data.
+ * @param[out] pOut points to the block of output data.
+ * @param[out] pErr points to the block of error data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_lms_norm_f32(
+ arm_lms_norm_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pRef,
+ float32_t * pOut,
+ float32_t * pErr,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for floating-point normalized LMS filter.
+ * @param[in] S points to an instance of the floating-point LMS filter structure.
+ * @param[in] numTaps number of filter coefficients.
+ * @param[in] pCoeffs points to coefficient buffer.
+ * @param[in] pState points to state buffer.
+ * @param[in] mu step size that controls filter coefficient updates.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_lms_norm_init_f32(
+ arm_lms_norm_instance_f32 * S,
+ uint16_t numTaps,
+ float32_t * pCoeffs,
+ float32_t * pState,
+ float32_t mu,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Instance structure for the Q31 normalized LMS filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+ q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */
+ q31_t mu; /**< step size that controls filter coefficient updates. */
+ uint8_t postShift; /**< bit shift applied to coefficients. */
+ q31_t *recipTable; /**< points to the reciprocal initial value table. */
+ q31_t energy; /**< saves previous frame energy. */
+ q31_t x0; /**< saves previous input sample. */
+ } arm_lms_norm_instance_q31;
+
+
+ /**
+ * @brief Processing function for Q31 normalized LMS filter.
+ * @param[in] S points to an instance of the Q31 normalized LMS filter structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[in] pRef points to the block of reference data.
+ * @param[out] pOut points to the block of output data.
+ * @param[out] pErr points to the block of error data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_lms_norm_q31(
+ arm_lms_norm_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pRef,
+ q31_t * pOut,
+ q31_t * pErr,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for Q31 normalized LMS filter.
+ * @param[in] S points to an instance of the Q31 normalized LMS filter structure.
+ * @param[in] numTaps number of filter coefficients.
+ * @param[in] pCoeffs points to coefficient buffer.
+ * @param[in] pState points to state buffer.
+ * @param[in] mu step size that controls filter coefficient updates.
+ * @param[in] blockSize number of samples to process.
+ * @param[in] postShift bit shift applied to coefficients.
+ */
+ void arm_lms_norm_init_q31(
+ arm_lms_norm_instance_q31 * S,
+ uint16_t numTaps,
+ q31_t * pCoeffs,
+ q31_t * pState,
+ q31_t mu,
+ uint32_t blockSize,
+ uint8_t postShift);
+
+
+ /**
+ * @brief Instance structure for the Q15 normalized LMS filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< Number of coefficients in the filter. */
+ q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+ q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */
+ q15_t mu; /**< step size that controls filter coefficient updates. */
+ uint8_t postShift; /**< bit shift applied to coefficients. */
+ q15_t *recipTable; /**< Points to the reciprocal initial value table. */
+ q15_t energy; /**< saves previous frame energy. */
+ q15_t x0; /**< saves previous input sample. */
+ } arm_lms_norm_instance_q15;
+
+
+ /**
+ * @brief Processing function for Q15 normalized LMS filter.
+ * @param[in] S points to an instance of the Q15 normalized LMS filter structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[in] pRef points to the block of reference data.
+ * @param[out] pOut points to the block of output data.
+ * @param[out] pErr points to the block of error data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_lms_norm_q15(
+ arm_lms_norm_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pRef,
+ q15_t * pOut,
+ q15_t * pErr,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for Q15 normalized LMS filter.
+ * @param[in] S points to an instance of the Q15 normalized LMS filter structure.
+ * @param[in] numTaps number of filter coefficients.
+ * @param[in] pCoeffs points to coefficient buffer.
+ * @param[in] pState points to state buffer.
+ * @param[in] mu step size that controls filter coefficient updates.
+ * @param[in] blockSize number of samples to process.
+ * @param[in] postShift bit shift applied to coefficients.
+ */
+ void arm_lms_norm_init_q15(
+ arm_lms_norm_instance_q15 * S,
+ uint16_t numTaps,
+ q15_t * pCoeffs,
+ q15_t * pState,
+ q15_t mu,
+ uint32_t blockSize,
+ uint8_t postShift);
+
+
+ /**
+ * @brief Correlation of floating-point sequences.
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1.
+ */
+ void arm_correlate_f32(
+ float32_t * pSrcA,
+ uint32_t srcALen,
+ float32_t * pSrcB,
+ uint32_t srcBLen,
+ float32_t * pDst);
+
+
+ /**
+ * @brief Correlation of Q15 sequences
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1.
+ * @param[in] pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+ */
+ void arm_correlate_opt_q15(
+ q15_t * pSrcA,
+ uint32_t srcALen,
+ q15_t * pSrcB,
+ uint32_t srcBLen,
+ q15_t * pDst,
+ q15_t * pScratch);
+
+
+ /**
+ * @brief Correlation of Q15 sequences.
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1.
+ */
+
+ void arm_correlate_q15(
+ q15_t * pSrcA,
+ uint32_t srcALen,
+ q15_t * pSrcB,
+ uint32_t srcBLen,
+ q15_t * pDst);
+
+
+ /**
+ * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4.
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1.
+ */
+
+ void arm_correlate_fast_q15(
+ q15_t * pSrcA,
+ uint32_t srcALen,
+ q15_t * pSrcB,
+ uint32_t srcBLen,
+ q15_t * pDst);
+
+
+ /**
+ * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4.
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1.
+ * @param[in] pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+ */
+ void arm_correlate_fast_opt_q15(
+ q15_t * pSrcA,
+ uint32_t srcALen,
+ q15_t * pSrcB,
+ uint32_t srcBLen,
+ q15_t * pDst,
+ q15_t * pScratch);
+
+
+ /**
+ * @brief Correlation of Q31 sequences.
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1.
+ */
+ void arm_correlate_q31(
+ q31_t * pSrcA,
+ uint32_t srcALen,
+ q31_t * pSrcB,
+ uint32_t srcBLen,
+ q31_t * pDst);
+
+
+ /**
+ * @brief Correlation of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1.
+ */
+ void arm_correlate_fast_q31(
+ q31_t * pSrcA,
+ uint32_t srcALen,
+ q31_t * pSrcB,
+ uint32_t srcBLen,
+ q31_t * pDst);
+
+
+ /**
+ * @brief Correlation of Q7 sequences.
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1.
+ * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+ * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen).
+ */
+ void arm_correlate_opt_q7(
+ q7_t * pSrcA,
+ uint32_t srcALen,
+ q7_t * pSrcB,
+ uint32_t srcBLen,
+ q7_t * pDst,
+ q15_t * pScratch1,
+ q15_t * pScratch2);
+
+
+ /**
+ * @brief Correlation of Q7 sequences.
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1.
+ */
+ void arm_correlate_q7(
+ q7_t * pSrcA,
+ uint32_t srcALen,
+ q7_t * pSrcB,
+ uint32_t srcBLen,
+ q7_t * pDst);
+
+
+ /**
+ * @brief Instance structure for the floating-point sparse FIR filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */
+ float32_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */
+ float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/
+ uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */
+ int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */
+ } arm_fir_sparse_instance_f32;
+
+ /**
+ * @brief Instance structure for the Q31 sparse FIR filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */
+ q31_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */
+ q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/
+ uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */
+ int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */
+ } arm_fir_sparse_instance_q31;
+
+ /**
+ * @brief Instance structure for the Q15 sparse FIR filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */
+ q15_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */
+ q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/
+ uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */
+ int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */
+ } arm_fir_sparse_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q7 sparse FIR filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */
+ q7_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */
+ q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/
+ uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */
+ int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */
+ } arm_fir_sparse_instance_q7;
+
+
+ /**
+ * @brief Processing function for the floating-point sparse FIR filter.
+ * @param[in] S points to an instance of the floating-point sparse FIR structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data
+ * @param[in] pScratchIn points to a temporary buffer of size blockSize.
+ * @param[in] blockSize number of input samples to process per call.
+ */
+ void arm_fir_sparse_f32(
+ arm_fir_sparse_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pDst,
+ float32_t * pScratchIn,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the floating-point sparse FIR filter.
+ * @param[in,out] S points to an instance of the floating-point sparse FIR structure.
+ * @param[in] numTaps number of nonzero coefficients in the filter.
+ * @param[in] pCoeffs points to the array of filter coefficients.
+ * @param[in] pState points to the state buffer.
+ * @param[in] pTapDelay points to the array of offset times.
+ * @param[in] maxDelay maximum offset time supported.
+ * @param[in] blockSize number of samples that will be processed per block.
+ */
+ void arm_fir_sparse_init_f32(
+ arm_fir_sparse_instance_f32 * S,
+ uint16_t numTaps,
+ float32_t * pCoeffs,
+ float32_t * pState,
+ int32_t * pTapDelay,
+ uint16_t maxDelay,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the Q31 sparse FIR filter.
+ * @param[in] S points to an instance of the Q31 sparse FIR structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data
+ * @param[in] pScratchIn points to a temporary buffer of size blockSize.
+ * @param[in] blockSize number of input samples to process per call.
+ */
+ void arm_fir_sparse_q31(
+ arm_fir_sparse_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ q31_t * pScratchIn,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the Q31 sparse FIR filter.
+ * @param[in,out] S points to an instance of the Q31 sparse FIR structure.
+ * @param[in] numTaps number of nonzero coefficients in the filter.
+ * @param[in] pCoeffs points to the array of filter coefficients.
+ * @param[in] pState points to the state buffer.
+ * @param[in] pTapDelay points to the array of offset times.
+ * @param[in] maxDelay maximum offset time supported.
+ * @param[in] blockSize number of samples that will be processed per block.
+ */
+ void arm_fir_sparse_init_q31(
+ arm_fir_sparse_instance_q31 * S,
+ uint16_t numTaps,
+ q31_t * pCoeffs,
+ q31_t * pState,
+ int32_t * pTapDelay,
+ uint16_t maxDelay,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the Q15 sparse FIR filter.
+ * @param[in] S points to an instance of the Q15 sparse FIR structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data
+ * @param[in] pScratchIn points to a temporary buffer of size blockSize.
+ * @param[in] pScratchOut points to a temporary buffer of size blockSize.
+ * @param[in] blockSize number of input samples to process per call.
+ */
+ void arm_fir_sparse_q15(
+ arm_fir_sparse_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ q15_t * pScratchIn,
+ q31_t * pScratchOut,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the Q15 sparse FIR filter.
+ * @param[in,out] S points to an instance of the Q15 sparse FIR structure.
+ * @param[in] numTaps number of nonzero coefficients in the filter.
+ * @param[in] pCoeffs points to the array of filter coefficients.
+ * @param[in] pState points to the state buffer.
+ * @param[in] pTapDelay points to the array of offset times.
+ * @param[in] maxDelay maximum offset time supported.
+ * @param[in] blockSize number of samples that will be processed per block.
+ */
+ void arm_fir_sparse_init_q15(
+ arm_fir_sparse_instance_q15 * S,
+ uint16_t numTaps,
+ q15_t * pCoeffs,
+ q15_t * pState,
+ int32_t * pTapDelay,
+ uint16_t maxDelay,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the Q7 sparse FIR filter.
+ * @param[in] S points to an instance of the Q7 sparse FIR structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data
+ * @param[in] pScratchIn points to a temporary buffer of size blockSize.
+ * @param[in] pScratchOut points to a temporary buffer of size blockSize.
+ * @param[in] blockSize number of input samples to process per call.
+ */
+ void arm_fir_sparse_q7(
+ arm_fir_sparse_instance_q7 * S,
+ q7_t * pSrc,
+ q7_t * pDst,
+ q7_t * pScratchIn,
+ q31_t * pScratchOut,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the Q7 sparse FIR filter.
+ * @param[in,out] S points to an instance of the Q7 sparse FIR structure.
+ * @param[in] numTaps number of nonzero coefficients in the filter.
+ * @param[in] pCoeffs points to the array of filter coefficients.
+ * @param[in] pState points to the state buffer.
+ * @param[in] pTapDelay points to the array of offset times.
+ * @param[in] maxDelay maximum offset time supported.
+ * @param[in] blockSize number of samples that will be processed per block.
+ */
+ void arm_fir_sparse_init_q7(
+ arm_fir_sparse_instance_q7 * S,
+ uint16_t numTaps,
+ q7_t * pCoeffs,
+ q7_t * pState,
+ int32_t * pTapDelay,
+ uint16_t maxDelay,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Floating-point sin_cos function.
+ * @param[in] theta input value in degrees
+ * @param[out] pSinVal points to the processed sine output.
+ * @param[out] pCosVal points to the processed cos output.
+ */
+ void arm_sin_cos_f32(
+ float32_t theta,
+ float32_t * pSinVal,
+ float32_t * pCosVal);
+
+
+ /**
+ * @brief Q31 sin_cos function.
+ * @param[in] theta scaled input value in degrees
+ * @param[out] pSinVal points to the processed sine output.
+ * @param[out] pCosVal points to the processed cosine output.
+ */
+ void arm_sin_cos_q31(
+ q31_t theta,
+ q31_t * pSinVal,
+ q31_t * pCosVal);
+
+
+ /**
+ * @brief Floating-point complex conjugate.
+ * @param[in] pSrc points to the input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] numSamples number of complex samples in each vector
+ */
+ void arm_cmplx_conj_f32(
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t numSamples);
+
+ /**
+ * @brief Q31 complex conjugate.
+ * @param[in] pSrc points to the input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] numSamples number of complex samples in each vector
+ */
+ void arm_cmplx_conj_q31(
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t numSamples);
+
+
+ /**
+ * @brief Q15 complex conjugate.
+ * @param[in] pSrc points to the input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] numSamples number of complex samples in each vector
+ */
+ void arm_cmplx_conj_q15(
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t numSamples);
+
+
+ /**
+ * @brief Floating-point complex magnitude squared
+ * @param[in] pSrc points to the complex input vector
+ * @param[out] pDst points to the real output vector
+ * @param[in] numSamples number of complex samples in the input vector
+ */
+ void arm_cmplx_mag_squared_f32(
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t numSamples);
+
+
+ /**
+ * @brief Q31 complex magnitude squared
+ * @param[in] pSrc points to the complex input vector
+ * @param[out] pDst points to the real output vector
+ * @param[in] numSamples number of complex samples in the input vector
+ */
+ void arm_cmplx_mag_squared_q31(
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t numSamples);
+
+
+ /**
+ * @brief Q15 complex magnitude squared
+ * @param[in] pSrc points to the complex input vector
+ * @param[out] pDst points to the real output vector
+ * @param[in] numSamples number of complex samples in the input vector
+ */
+ void arm_cmplx_mag_squared_q15(
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t numSamples);
+
+
+ /**
+ * @ingroup groupController
+ */
+
+ /**
+ * @defgroup PID PID Motor Control
+ *
+ * A Proportional Integral Derivative (PID) controller is a generic feedback control
+ * loop mechanism widely used in industrial control systems.
+ * A PID controller is the most commonly used type of feedback controller.
+ *
+ * This set of functions implements (PID) controllers
+ * for Q15, Q31, and floating-point data types. The functions operate on a single sample
+ * of data and each call to the function returns a single processed value.
+ * S
points to an instance of the PID control data structure. in
+ * is the input sample value. The functions return the output value.
+ *
+ * \par Algorithm:
+ *
+ * y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2]
+ * A0 = Kp + Ki + Kd
+ * A1 = (-Kp ) - (2 * Kd )
+ * A2 = Kd
+ *
+ * \par
+ * where \c Kp is proportional constant, \c Ki is Integral constant and \c Kd is Derivative constant
+ *
+ * \par
+ * \image html PID.gif "Proportional Integral Derivative Controller"
+ *
+ * \par
+ * The PID controller calculates an "error" value as the difference between
+ * the measured output and the reference input.
+ * The controller attempts to minimize the error by adjusting the process control inputs.
+ * The proportional value determines the reaction to the current error,
+ * the integral value determines the reaction based on the sum of recent errors,
+ * and the derivative value determines the reaction based on the rate at which the error has been changing.
+ *
+ * \par Instance Structure
+ * The Gains A0, A1, A2 and state variables for a PID controller are stored together in an instance data structure.
+ * A separate instance structure must be defined for each PID Controller.
+ * There are separate instance structure declarations for each of the 3 supported data types.
+ *
+ * \par Reset Functions
+ * There is also an associated reset function for each data type which clears the state array.
+ *
+ * \par Initialization Functions
+ * There is also an associated initialization function for each data type.
+ * The initialization function performs the following operations:
+ * - Initializes the Gains A0, A1, A2 from Kp,Ki, Kd gains.
+ * - Zeros out the values in the state buffer.
+ *
+ * \par
+ * Instance structure cannot be placed into a const data section and it is recommended to use the initialization function.
+ *
+ * \par Fixed-Point Behavior
+ * Care must be taken when using the fixed-point versions of the PID Controller functions.
+ * In particular, the overflow and saturation behavior of the accumulator used in each function must be considered.
+ * Refer to the function specific documentation below for usage guidelines.
+ */
+
+ /**
+ * @addtogroup PID
+ * @{
+ */
+
+ /**
+ * @brief Process function for the floating-point PID Control.
+ * @param[in,out] S is an instance of the floating-point PID Control structure
+ * @param[in] in input sample to process
+ * @return out processed output sample.
+ */
+ static __INLINE float32_t arm_pid_f32(
+ arm_pid_instance_f32 * S,
+ float32_t in)
+ {
+ float32_t out;
+
+ /* y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2] */
+ out = (S->A0 * in) +
+ (S->A1 * S->state[0]) + (S->A2 * S->state[1]) + (S->state[2]);
+
+ /* Update state */
+ S->state[1] = S->state[0];
+ S->state[0] = in;
+ S->state[2] = out;
+
+ /* return to application */
+ return (out);
+
+ }
+
+ /**
+ * @brief Process function for the Q31 PID Control.
+ * @param[in,out] S points to an instance of the Q31 PID Control structure
+ * @param[in] in input sample to process
+ * @return out processed output sample.
+ *
+ * Scaling and Overflow Behavior:
+ * \par
+ * The function is implemented using an internal 64-bit accumulator.
+ * The accumulator has a 2.62 format and maintains full precision of the intermediate multiplication results but provides only a single guard bit.
+ * Thus, if the accumulator result overflows it wraps around rather than clip.
+ * In order to avoid overflows completely the input signal must be scaled down by 2 bits as there are four additions.
+ * After all multiply-accumulates are performed, the 2.62 accumulator is truncated to 1.32 format and then saturated to 1.31 format.
+ */
+ static __INLINE q31_t arm_pid_q31(
+ arm_pid_instance_q31 * S,
+ q31_t in)
+ {
+ q63_t acc;
+ q31_t out;
+
+ /* acc = A0 * x[n] */
+ acc = (q63_t) S->A0 * in;
+
+ /* acc += A1 * x[n-1] */
+ acc += (q63_t) S->A1 * S->state[0];
+
+ /* acc += A2 * x[n-2] */
+ acc += (q63_t) S->A2 * S->state[1];
+
+ /* convert output to 1.31 format to add y[n-1] */
+ out = (q31_t) (acc >> 31u);
+
+ /* out += y[n-1] */
+ out += S->state[2];
+
+ /* Update state */
+ S->state[1] = S->state[0];
+ S->state[0] = in;
+ S->state[2] = out;
+
+ /* return to application */
+ return (out);
+ }
+
+
+ /**
+ * @brief Process function for the Q15 PID Control.
+ * @param[in,out] S points to an instance of the Q15 PID Control structure
+ * @param[in] in input sample to process
+ * @return out processed output sample.
+ *
+ * Scaling and Overflow Behavior:
+ * \par
+ * The function is implemented using a 64-bit internal accumulator.
+ * Both Gains and state variables are represented in 1.15 format and multiplications yield a 2.30 result.
+ * The 2.30 intermediate results are accumulated in a 64-bit accumulator in 34.30 format.
+ * There is no risk of internal overflow with this approach and the full precision of intermediate multiplications is preserved.
+ * After all additions have been performed, the accumulator is truncated to 34.15 format by discarding low 15 bits.
+ * Lastly, the accumulator is saturated to yield a result in 1.15 format.
+ */
+ static __INLINE q15_t arm_pid_q15(
+ arm_pid_instance_q15 * S,
+ q15_t in)
+ {
+ q63_t acc;
+ q15_t out;
+
+#ifndef ARM_MATH_CM0_FAMILY
+ __SIMD32_TYPE *vstate;
+
+ /* Implementation of PID controller */
+
+ /* acc = A0 * x[n] */
+ acc = (q31_t) __SMUAD((uint32_t)S->A0, (uint32_t)in);
+
+ /* acc += A1 * x[n-1] + A2 * x[n-2] */
+ vstate = __SIMD32_CONST(S->state);
+ acc = (q63_t)__SMLALD((uint32_t)S->A1, (uint32_t)*vstate, (uint64_t)acc);
+#else
+ /* acc = A0 * x[n] */
+ acc = ((q31_t) S->A0) * in;
+
+ /* acc += A1 * x[n-1] + A2 * x[n-2] */
+ acc += (q31_t) S->A1 * S->state[0];
+ acc += (q31_t) S->A2 * S->state[1];
+#endif
+
+ /* acc += y[n-1] */
+ acc += (q31_t) S->state[2] << 15;
+
+ /* saturate the output */
+ out = (q15_t) (__SSAT((acc >> 15), 16));
+
+ /* Update state */
+ S->state[1] = S->state[0];
+ S->state[0] = in;
+ S->state[2] = out;
+
+ /* return to application */
+ return (out);
+ }
+
+ /**
+ * @} end of PID group
+ */
+
+
+ /**
+ * @brief Floating-point matrix inverse.
+ * @param[in] src points to the instance of the input floating-point matrix structure.
+ * @param[out] dst points to the instance of the output floating-point matrix structure.
+ * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match.
+ * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR.
+ */
+ arm_status arm_mat_inverse_f32(
+ const arm_matrix_instance_f32 * src,
+ arm_matrix_instance_f32 * dst);
+
+
+ /**
+ * @brief Floating-point matrix inverse.
+ * @param[in] src points to the instance of the input floating-point matrix structure.
+ * @param[out] dst points to the instance of the output floating-point matrix structure.
+ * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match.
+ * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR.
+ */
+ arm_status arm_mat_inverse_f64(
+ const arm_matrix_instance_f64 * src,
+ arm_matrix_instance_f64 * dst);
+
+
+
+ /**
+ * @ingroup groupController
+ */
+
+ /**
+ * @defgroup clarke Vector Clarke Transform
+ * Forward Clarke transform converts the instantaneous stator phases into a two-coordinate time invariant vector.
+ * Generally the Clarke transform uses three-phase currents Ia, Ib and Ic
to calculate currents
+ * in the two-phase orthogonal stator axis Ialpha
and Ibeta
.
+ * When Ialpha
is superposed with Ia
as shown in the figure below
+ * \image html clarke.gif Stator current space vector and its components in (a,b).
+ * and Ia + Ib + Ic = 0
, in this condition Ialpha
and Ibeta
+ * can be calculated using only Ia
and Ib
.
+ *
+ * The function operates on a single sample of data and each call to the function returns the processed output.
+ * The library provides separate functions for Q31 and floating-point data types.
+ * \par Algorithm
+ * \image html clarkeFormula.gif
+ * where Ia
and Ib
are the instantaneous stator phases and
+ * pIalpha
and pIbeta
are the two coordinates of time invariant vector.
+ * \par Fixed-Point Behavior
+ * Care must be taken when using the Q31 version of the Clarke transform.
+ * In particular, the overflow and saturation behavior of the accumulator used must be considered.
+ * Refer to the function specific documentation below for usage guidelines.
+ */
+
+ /**
+ * @addtogroup clarke
+ * @{
+ */
+
+ /**
+ *
+ * @brief Floating-point Clarke transform
+ * @param[in] Ia input three-phase coordinate a
+ * @param[in] Ib input three-phase coordinate b
+ * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha
+ * @param[out] pIbeta points to output two-phase orthogonal vector axis beta
+ */
+ static __INLINE void arm_clarke_f32(
+ float32_t Ia,
+ float32_t Ib,
+ float32_t * pIalpha,
+ float32_t * pIbeta)
+ {
+ /* Calculate pIalpha using the equation, pIalpha = Ia */
+ *pIalpha = Ia;
+
+ /* Calculate pIbeta using the equation, pIbeta = (1/sqrt(3)) * Ia + (2/sqrt(3)) * Ib */
+ *pIbeta = ((float32_t) 0.57735026919 * Ia + (float32_t) 1.15470053838 * Ib);
+ }
+
+
+ /**
+ * @brief Clarke transform for Q31 version
+ * @param[in] Ia input three-phase coordinate a
+ * @param[in] Ib input three-phase coordinate b
+ * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha
+ * @param[out] pIbeta points to output two-phase orthogonal vector axis beta
+ *
+ * Scaling and Overflow Behavior:
+ * \par
+ * The function is implemented using an internal 32-bit accumulator.
+ * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
+ * There is saturation on the addition, hence there is no risk of overflow.
+ */
+ static __INLINE void arm_clarke_q31(
+ q31_t Ia,
+ q31_t Ib,
+ q31_t * pIalpha,
+ q31_t * pIbeta)
+ {
+ q31_t product1, product2; /* Temporary variables used to store intermediate results */
+
+ /* Calculating pIalpha from Ia by equation pIalpha = Ia */
+ *pIalpha = Ia;
+
+ /* Intermediate product is calculated by (1/(sqrt(3)) * Ia) */
+ product1 = (q31_t) (((q63_t) Ia * 0x24F34E8B) >> 30);
+
+ /* Intermediate product is calculated by (2/sqrt(3) * Ib) */
+ product2 = (q31_t) (((q63_t) Ib * 0x49E69D16) >> 30);
+
+ /* pIbeta is calculated by adding the intermediate products */
+ *pIbeta = __QADD(product1, product2);
+ }
+
+ /**
+ * @} end of clarke group
+ */
+
+ /**
+ * @brief Converts the elements of the Q7 vector to Q31 vector.
+ * @param[in] pSrc input pointer
+ * @param[out] pDst output pointer
+ * @param[in] blockSize number of samples to process
+ */
+ void arm_q7_to_q31(
+ q7_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+
+ /**
+ * @ingroup groupController
+ */
+
+ /**
+ * @defgroup inv_clarke Vector Inverse Clarke Transform
+ * Inverse Clarke transform converts the two-coordinate time invariant vector into instantaneous stator phases.
+ *
+ * The function operates on a single sample of data and each call to the function returns the processed output.
+ * The library provides separate functions for Q31 and floating-point data types.
+ * \par Algorithm
+ * \image html clarkeInvFormula.gif
+ * where pIa
and pIb
are the instantaneous stator phases and
+ * Ialpha
and Ibeta
are the two coordinates of time invariant vector.
+ * \par Fixed-Point Behavior
+ * Care must be taken when using the Q31 version of the Clarke transform.
+ * In particular, the overflow and saturation behavior of the accumulator used must be considered.
+ * Refer to the function specific documentation below for usage guidelines.
+ */
+
+ /**
+ * @addtogroup inv_clarke
+ * @{
+ */
+
+ /**
+ * @brief Floating-point Inverse Clarke transform
+ * @param[in] Ialpha input two-phase orthogonal vector axis alpha
+ * @param[in] Ibeta input two-phase orthogonal vector axis beta
+ * @param[out] pIa points to output three-phase coordinate a
+ * @param[out] pIb points to output three-phase coordinate b
+ */
+ static __INLINE void arm_inv_clarke_f32(
+ float32_t Ialpha,
+ float32_t Ibeta,
+ float32_t * pIa,
+ float32_t * pIb)
+ {
+ /* Calculating pIa from Ialpha by equation pIa = Ialpha */
+ *pIa = Ialpha;
+
+ /* Calculating pIb from Ialpha and Ibeta by equation pIb = -(1/2) * Ialpha + (sqrt(3)/2) * Ibeta */
+ *pIb = -0.5f * Ialpha + 0.8660254039f * Ibeta;
+ }
+
+
+ /**
+ * @brief Inverse Clarke transform for Q31 version
+ * @param[in] Ialpha input two-phase orthogonal vector axis alpha
+ * @param[in] Ibeta input two-phase orthogonal vector axis beta
+ * @param[out] pIa points to output three-phase coordinate a
+ * @param[out] pIb points to output three-phase coordinate b
+ *
+ * Scaling and Overflow Behavior:
+ * \par
+ * The function is implemented using an internal 32-bit accumulator.
+ * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
+ * There is saturation on the subtraction, hence there is no risk of overflow.
+ */
+ static __INLINE void arm_inv_clarke_q31(
+ q31_t Ialpha,
+ q31_t Ibeta,
+ q31_t * pIa,
+ q31_t * pIb)
+ {
+ q31_t product1, product2; /* Temporary variables used to store intermediate results */
+
+ /* Calculating pIa from Ialpha by equation pIa = Ialpha */
+ *pIa = Ialpha;
+
+ /* Intermediate product is calculated by (1/(2*sqrt(3)) * Ia) */
+ product1 = (q31_t) (((q63_t) (Ialpha) * (0x40000000)) >> 31);
+
+ /* Intermediate product is calculated by (1/sqrt(3) * pIb) */
+ product2 = (q31_t) (((q63_t) (Ibeta) * (0x6ED9EBA1)) >> 31);
+
+ /* pIb is calculated by subtracting the products */
+ *pIb = __QSUB(product2, product1);
+ }
+
+ /**
+ * @} end of inv_clarke group
+ */
+
+ /**
+ * @brief Converts the elements of the Q7 vector to Q15 vector.
+ * @param[in] pSrc input pointer
+ * @param[out] pDst output pointer
+ * @param[in] blockSize number of samples to process
+ */
+ void arm_q7_to_q15(
+ q7_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+
+ /**
+ * @ingroup groupController
+ */
+
+ /**
+ * @defgroup park Vector Park Transform
+ *
+ * Forward Park transform converts the input two-coordinate vector to flux and torque components.
+ * The Park transform can be used to realize the transformation of the Ialpha
and the Ibeta
currents
+ * from the stationary to the moving reference frame and control the spatial relationship between
+ * the stator vector current and rotor flux vector.
+ * If we consider the d axis aligned with the rotor flux, the diagram below shows the
+ * current vector and the relationship from the two reference frames:
+ * \image html park.gif "Stator current space vector and its component in (a,b) and in the d,q rotating reference frame"
+ *
+ * The function operates on a single sample of data and each call to the function returns the processed output.
+ * The library provides separate functions for Q31 and floating-point data types.
+ * \par Algorithm
+ * \image html parkFormula.gif
+ * where Ialpha
and Ibeta
are the stator vector components,
+ * pId
and pIq
are rotor vector components and cosVal
and sinVal
are the
+ * cosine and sine values of theta (rotor flux position).
+ * \par Fixed-Point Behavior
+ * Care must be taken when using the Q31 version of the Park transform.
+ * In particular, the overflow and saturation behavior of the accumulator used must be considered.
+ * Refer to the function specific documentation below for usage guidelines.
+ */
+
+ /**
+ * @addtogroup park
+ * @{
+ */
+
+ /**
+ * @brief Floating-point Park transform
+ * @param[in] Ialpha input two-phase vector coordinate alpha
+ * @param[in] Ibeta input two-phase vector coordinate beta
+ * @param[out] pId points to output rotor reference frame d
+ * @param[out] pIq points to output rotor reference frame q
+ * @param[in] sinVal sine value of rotation angle theta
+ * @param[in] cosVal cosine value of rotation angle theta
+ *
+ * The function implements the forward Park transform.
+ *
+ */
+ static __INLINE void arm_park_f32(
+ float32_t Ialpha,
+ float32_t Ibeta,
+ float32_t * pId,
+ float32_t * pIq,
+ float32_t sinVal,
+ float32_t cosVal)
+ {
+ /* Calculate pId using the equation, pId = Ialpha * cosVal + Ibeta * sinVal */
+ *pId = Ialpha * cosVal + Ibeta * sinVal;
+
+ /* Calculate pIq using the equation, pIq = - Ialpha * sinVal + Ibeta * cosVal */
+ *pIq = -Ialpha * sinVal + Ibeta * cosVal;
+ }
+
+
+ /**
+ * @brief Park transform for Q31 version
+ * @param[in] Ialpha input two-phase vector coordinate alpha
+ * @param[in] Ibeta input two-phase vector coordinate beta
+ * @param[out] pId points to output rotor reference frame d
+ * @param[out] pIq points to output rotor reference frame q
+ * @param[in] sinVal sine value of rotation angle theta
+ * @param[in] cosVal cosine value of rotation angle theta
+ *
+ * Scaling and Overflow Behavior:
+ * \par
+ * The function is implemented using an internal 32-bit accumulator.
+ * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
+ * There is saturation on the addition and subtraction, hence there is no risk of overflow.
+ */
+ static __INLINE void arm_park_q31(
+ q31_t Ialpha,
+ q31_t Ibeta,
+ q31_t * pId,
+ q31_t * pIq,
+ q31_t sinVal,
+ q31_t cosVal)
+ {
+ q31_t product1, product2; /* Temporary variables used to store intermediate results */
+ q31_t product3, product4; /* Temporary variables used to store intermediate results */
+
+ /* Intermediate product is calculated by (Ialpha * cosVal) */
+ product1 = (q31_t) (((q63_t) (Ialpha) * (cosVal)) >> 31);
+
+ /* Intermediate product is calculated by (Ibeta * sinVal) */
+ product2 = (q31_t) (((q63_t) (Ibeta) * (sinVal)) >> 31);
+
+
+ /* Intermediate product is calculated by (Ialpha * sinVal) */
+ product3 = (q31_t) (((q63_t) (Ialpha) * (sinVal)) >> 31);
+
+ /* Intermediate product is calculated by (Ibeta * cosVal) */
+ product4 = (q31_t) (((q63_t) (Ibeta) * (cosVal)) >> 31);
+
+ /* Calculate pId by adding the two intermediate products 1 and 2 */
+ *pId = __QADD(product1, product2);
+
+ /* Calculate pIq by subtracting the two intermediate products 3 from 4 */
+ *pIq = __QSUB(product4, product3);
+ }
+
+ /**
+ * @} end of park group
+ */
+
+ /**
+ * @brief Converts the elements of the Q7 vector to floating-point vector.
+ * @param[in] pSrc is input pointer
+ * @param[out] pDst is output pointer
+ * @param[in] blockSize is the number of samples to process
+ */
+ void arm_q7_to_float(
+ q7_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @ingroup groupController
+ */
+
+ /**
+ * @defgroup inv_park Vector Inverse Park transform
+ * Inverse Park transform converts the input flux and torque components to two-coordinate vector.
+ *
+ * The function operates on a single sample of data and each call to the function returns the processed output.
+ * The library provides separate functions for Q31 and floating-point data types.
+ * \par Algorithm
+ * \image html parkInvFormula.gif
+ * where pIalpha
and pIbeta
are the stator vector components,
+ * Id
and Iq
are rotor vector components and cosVal
and sinVal
are the
+ * cosine and sine values of theta (rotor flux position).
+ * \par Fixed-Point Behavior
+ * Care must be taken when using the Q31 version of the Park transform.
+ * In particular, the overflow and saturation behavior of the accumulator used must be considered.
+ * Refer to the function specific documentation below for usage guidelines.
+ */
+
+ /**
+ * @addtogroup inv_park
+ * @{
+ */
+
+ /**
+ * @brief Floating-point Inverse Park transform
+ * @param[in] Id input coordinate of rotor reference frame d
+ * @param[in] Iq input coordinate of rotor reference frame q
+ * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha
+ * @param[out] pIbeta points to output two-phase orthogonal vector axis beta
+ * @param[in] sinVal sine value of rotation angle theta
+ * @param[in] cosVal cosine value of rotation angle theta
+ */
+ static __INLINE void arm_inv_park_f32(
+ float32_t Id,
+ float32_t Iq,
+ float32_t * pIalpha,
+ float32_t * pIbeta,
+ float32_t sinVal,
+ float32_t cosVal)
+ {
+ /* Calculate pIalpha using the equation, pIalpha = Id * cosVal - Iq * sinVal */
+ *pIalpha = Id * cosVal - Iq * sinVal;
+
+ /* Calculate pIbeta using the equation, pIbeta = Id * sinVal + Iq * cosVal */
+ *pIbeta = Id * sinVal + Iq * cosVal;
+ }
+
+
+ /**
+ * @brief Inverse Park transform for Q31 version
+ * @param[in] Id input coordinate of rotor reference frame d
+ * @param[in] Iq input coordinate of rotor reference frame q
+ * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha
+ * @param[out] pIbeta points to output two-phase orthogonal vector axis beta
+ * @param[in] sinVal sine value of rotation angle theta
+ * @param[in] cosVal cosine value of rotation angle theta
+ *
+ * Scaling and Overflow Behavior:
+ * \par
+ * The function is implemented using an internal 32-bit accumulator.
+ * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
+ * There is saturation on the addition, hence there is no risk of overflow.
+ */
+ static __INLINE void arm_inv_park_q31(
+ q31_t Id,
+ q31_t Iq,
+ q31_t * pIalpha,
+ q31_t * pIbeta,
+ q31_t sinVal,
+ q31_t cosVal)
+ {
+ q31_t product1, product2; /* Temporary variables used to store intermediate results */
+ q31_t product3, product4; /* Temporary variables used to store intermediate results */
+
+ /* Intermediate product is calculated by (Id * cosVal) */
+ product1 = (q31_t) (((q63_t) (Id) * (cosVal)) >> 31);
+
+ /* Intermediate product is calculated by (Iq * sinVal) */
+ product2 = (q31_t) (((q63_t) (Iq) * (sinVal)) >> 31);
+
+
+ /* Intermediate product is calculated by (Id * sinVal) */
+ product3 = (q31_t) (((q63_t) (Id) * (sinVal)) >> 31);
+
+ /* Intermediate product is calculated by (Iq * cosVal) */
+ product4 = (q31_t) (((q63_t) (Iq) * (cosVal)) >> 31);
+
+ /* Calculate pIalpha by using the two intermediate products 1 and 2 */
+ *pIalpha = __QSUB(product1, product2);
+
+ /* Calculate pIbeta by using the two intermediate products 3 and 4 */
+ *pIbeta = __QADD(product4, product3);
+ }
+
+ /**
+ * @} end of Inverse park group
+ */
+
+
+ /**
+ * @brief Converts the elements of the Q31 vector to floating-point vector.
+ * @param[in] pSrc is input pointer
+ * @param[out] pDst is output pointer
+ * @param[in] blockSize is the number of samples to process
+ */
+ void arm_q31_to_float(
+ q31_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @ingroup groupInterpolation
+ */
+
+ /**
+ * @defgroup LinearInterpolate Linear Interpolation
+ *
+ * Linear interpolation is a method of curve fitting using linear polynomials.
+ * Linear interpolation works by effectively drawing a straight line between two neighboring samples and returning the appropriate point along that line
+ *
+ * \par
+ * \image html LinearInterp.gif "Linear interpolation"
+ *
+ * \par
+ * A Linear Interpolate function calculates an output value(y), for the input(x)
+ * using linear interpolation of the input values x0, x1( nearest input values) and the output values y0 and y1(nearest output values)
+ *
+ * \par Algorithm:
+ *
+ * y = y0 + (x - x0) * ((y1 - y0)/(x1-x0))
+ * where x0, x1 are nearest values of input x
+ * y0, y1 are nearest values to output y
+ *
+ *
+ * \par
+ * This set of functions implements Linear interpolation process
+ * for Q7, Q15, Q31, and floating-point data types. The functions operate on a single
+ * sample of data and each call to the function returns a single processed value.
+ * S
points to an instance of the Linear Interpolate function data structure.
+ * x
is the input sample value. The functions returns the output value.
+ *
+ * \par
+ * if x is outside of the table boundary, Linear interpolation returns first value of the table
+ * if x is below input range and returns last value of table if x is above range.
+ */
+
+ /**
+ * @addtogroup LinearInterpolate
+ * @{
+ */
+
+ /**
+ * @brief Process function for the floating-point Linear Interpolation Function.
+ * @param[in,out] S is an instance of the floating-point Linear Interpolation structure
+ * @param[in] x input sample to process
+ * @return y processed output sample.
+ *
+ */
+ static __INLINE float32_t arm_linear_interp_f32(
+ arm_linear_interp_instance_f32 * S,
+ float32_t x)
+ {
+ float32_t y;
+ float32_t x0, x1; /* Nearest input values */
+ float32_t y0, y1; /* Nearest output values */
+ float32_t xSpacing = S->xSpacing; /* spacing between input values */
+ int32_t i; /* Index variable */
+ float32_t *pYData = S->pYData; /* pointer to output table */
+
+ /* Calculation of index */
+ i = (int32_t) ((x - S->x1) / xSpacing);
+
+ if(i < 0)
+ {
+ /* Iniatilize output for below specified range as least output value of table */
+ y = pYData[0];
+ }
+ else if((uint32_t)i >= S->nValues)
+ {
+ /* Iniatilize output for above specified range as last output value of table */
+ y = pYData[S->nValues - 1];
+ }
+ else
+ {
+ /* Calculation of nearest input values */
+ x0 = S->x1 + i * xSpacing;
+ x1 = S->x1 + (i + 1) * xSpacing;
+
+ /* Read of nearest output values */
+ y0 = pYData[i];
+ y1 = pYData[i + 1];
+
+ /* Calculation of output */
+ y = y0 + (x - x0) * ((y1 - y0) / (x1 - x0));
+
+ }
+
+ /* returns output value */
+ return (y);
+ }
+
+
+ /**
+ *
+ * @brief Process function for the Q31 Linear Interpolation Function.
+ * @param[in] pYData pointer to Q31 Linear Interpolation table
+ * @param[in] x input sample to process
+ * @param[in] nValues number of table values
+ * @return y processed output sample.
+ *
+ * \par
+ * Input sample x
is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part.
+ * This function can support maximum of table size 2^12.
+ *
+ */
+ static __INLINE q31_t arm_linear_interp_q31(
+ q31_t * pYData,
+ q31_t x,
+ uint32_t nValues)
+ {
+ q31_t y; /* output */
+ q31_t y0, y1; /* Nearest output values */
+ q31_t fract; /* fractional part */
+ int32_t index; /* Index to read nearest output values */
+
+ /* Input is in 12.20 format */
+ /* 12 bits for the table index */
+ /* Index value calculation */
+ index = ((x & (q31_t)0xFFF00000) >> 20);
+
+ if(index >= (int32_t)(nValues - 1))
+ {
+ return (pYData[nValues - 1]);
+ }
+ else if(index < 0)
+ {
+ return (pYData[0]);
+ }
+ else
+ {
+ /* 20 bits for the fractional part */
+ /* shift left by 11 to keep fract in 1.31 format */
+ fract = (x & 0x000FFFFF) << 11;
+
+ /* Read two nearest output values from the index in 1.31(q31) format */
+ y0 = pYData[index];
+ y1 = pYData[index + 1];
+
+ /* Calculation of y0 * (1-fract) and y is in 2.30 format */
+ y = ((q31_t) ((q63_t) y0 * (0x7FFFFFFF - fract) >> 32));
+
+ /* Calculation of y0 * (1-fract) + y1 *fract and y is in 2.30 format */
+ y += ((q31_t) (((q63_t) y1 * fract) >> 32));
+
+ /* Convert y to 1.31 format */
+ return (y << 1u);
+ }
+ }
+
+
+ /**
+ *
+ * @brief Process function for the Q15 Linear Interpolation Function.
+ * @param[in] pYData pointer to Q15 Linear Interpolation table
+ * @param[in] x input sample to process
+ * @param[in] nValues number of table values
+ * @return y processed output sample.
+ *
+ * \par
+ * Input sample x
is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part.
+ * This function can support maximum of table size 2^12.
+ *
+ */
+ static __INLINE q15_t arm_linear_interp_q15(
+ q15_t * pYData,
+ q31_t x,
+ uint32_t nValues)
+ {
+ q63_t y; /* output */
+ q15_t y0, y1; /* Nearest output values */
+ q31_t fract; /* fractional part */
+ int32_t index; /* Index to read nearest output values */
+
+ /* Input is in 12.20 format */
+ /* 12 bits for the table index */
+ /* Index value calculation */
+ index = ((x & (int32_t)0xFFF00000) >> 20);
+
+ if(index >= (int32_t)(nValues - 1))
+ {
+ return (pYData[nValues - 1]);
+ }
+ else if(index < 0)
+ {
+ return (pYData[0]);
+ }
+ else
+ {
+ /* 20 bits for the fractional part */
+ /* fract is in 12.20 format */
+ fract = (x & 0x000FFFFF);
+
+ /* Read two nearest output values from the index */
+ y0 = pYData[index];
+ y1 = pYData[index + 1];
+
+ /* Calculation of y0 * (1-fract) and y is in 13.35 format */
+ y = ((q63_t) y0 * (0xFFFFF - fract));
+
+ /* Calculation of (y0 * (1-fract) + y1 * fract) and y is in 13.35 format */
+ y += ((q63_t) y1 * (fract));
+
+ /* convert y to 1.15 format */
+ return (q15_t) (y >> 20);
+ }
+ }
+
+
+ /**
+ *
+ * @brief Process function for the Q7 Linear Interpolation Function.
+ * @param[in] pYData pointer to Q7 Linear Interpolation table
+ * @param[in] x input sample to process
+ * @param[in] nValues number of table values
+ * @return y processed output sample.
+ *
+ * \par
+ * Input sample x
is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part.
+ * This function can support maximum of table size 2^12.
+ */
+ static __INLINE q7_t arm_linear_interp_q7(
+ q7_t * pYData,
+ q31_t x,
+ uint32_t nValues)
+ {
+ q31_t y; /* output */
+ q7_t y0, y1; /* Nearest output values */
+ q31_t fract; /* fractional part */
+ uint32_t index; /* Index to read nearest output values */
+
+ /* Input is in 12.20 format */
+ /* 12 bits for the table index */
+ /* Index value calculation */
+ if (x < 0)
+ {
+ return (pYData[0]);
+ }
+ index = (x >> 20) & 0xfff;
+
+ if(index >= (nValues - 1))
+ {
+ return (pYData[nValues - 1]);
+ }
+ else
+ {
+ /* 20 bits for the fractional part */
+ /* fract is in 12.20 format */
+ fract = (x & 0x000FFFFF);
+
+ /* Read two nearest output values from the index and are in 1.7(q7) format */
+ y0 = pYData[index];
+ y1 = pYData[index + 1];
+
+ /* Calculation of y0 * (1-fract ) and y is in 13.27(q27) format */
+ y = ((y0 * (0xFFFFF - fract)));
+
+ /* Calculation of y1 * fract + y0 * (1-fract) and y is in 13.27(q27) format */
+ y += (y1 * fract);
+
+ /* convert y to 1.7(q7) format */
+ return (q7_t) (y >> 20);
+ }
+ }
+
+ /**
+ * @} end of LinearInterpolate group
+ */
+
+ /**
+ * @brief Fast approximation to the trigonometric sine function for floating-point data.
+ * @param[in] x input value in radians.
+ * @return sin(x).
+ */
+ float32_t arm_sin_f32(
+ float32_t x);
+
+
+ /**
+ * @brief Fast approximation to the trigonometric sine function for Q31 data.
+ * @param[in] x Scaled input value in radians.
+ * @return sin(x).
+ */
+ q31_t arm_sin_q31(
+ q31_t x);
+
+
+ /**
+ * @brief Fast approximation to the trigonometric sine function for Q15 data.
+ * @param[in] x Scaled input value in radians.
+ * @return sin(x).
+ */
+ q15_t arm_sin_q15(
+ q15_t x);
+
+
+ /**
+ * @brief Fast approximation to the trigonometric cosine function for floating-point data.
+ * @param[in] x input value in radians.
+ * @return cos(x).
+ */
+ float32_t arm_cos_f32(
+ float32_t x);
+
+
+ /**
+ * @brief Fast approximation to the trigonometric cosine function for Q31 data.
+ * @param[in] x Scaled input value in radians.
+ * @return cos(x).
+ */
+ q31_t arm_cos_q31(
+ q31_t x);
+
+
+ /**
+ * @brief Fast approximation to the trigonometric cosine function for Q15 data.
+ * @param[in] x Scaled input value in radians.
+ * @return cos(x).
+ */
+ q15_t arm_cos_q15(
+ q15_t x);
+
+
+ /**
+ * @ingroup groupFastMath
+ */
+
+
+ /**
+ * @defgroup SQRT Square Root
+ *
+ * Computes the square root of a number.
+ * There are separate functions for Q15, Q31, and floating-point data types.
+ * The square root function is computed using the Newton-Raphson algorithm.
+ * This is an iterative algorithm of the form:
+ *
+ * x1 = x0 - f(x0)/f'(x0)
+ *
+ * where x1
is the current estimate,
+ * x0
is the previous estimate, and
+ * f'(x0)
is the derivative of f()
evaluated at x0
.
+ * For the square root function, the algorithm reduces to:
+ *
+ * x0 = in/2 [initial guess]
+ * x1 = 1/2 * ( x0 + in / x0) [each iteration]
+ *
+ */
+
+
+ /**
+ * @addtogroup SQRT
+ * @{
+ */
+
+ /**
+ * @brief Floating-point square root function.
+ * @param[in] in input value.
+ * @param[out] pOut square root of input value.
+ * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if
+ * in
is negative value and returns zero output for negative values.
+ */
+ static __INLINE arm_status arm_sqrt_f32(
+ float32_t in,
+ float32_t * pOut)
+ {
+ if(in >= 0.0f)
+ {
+
+#if (__FPU_USED == 1) && defined ( __CC_ARM )
+ *pOut = __sqrtf(in);
+#elif (__FPU_USED == 1) && (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
+ *pOut = __builtin_sqrtf(in);
+#elif (__FPU_USED == 1) && defined(__GNUC__)
+ *pOut = __builtin_sqrtf(in);
+#elif (__FPU_USED == 1) && defined ( __ICCARM__ ) && (__VER__ >= 6040000)
+ __ASM("VSQRT.F32 %0,%1" : "=t"(*pOut) : "t"(in));
+#else
+ *pOut = sqrtf(in);
+#endif
+
+ return (ARM_MATH_SUCCESS);
+ }
+ else
+ {
+ *pOut = 0.0f;
+ return (ARM_MATH_ARGUMENT_ERROR);
+ }
+ }
+
+
+ /**
+ * @brief Q31 square root function.
+ * @param[in] in input value. The range of the input value is [0 +1) or 0x00000000 to 0x7FFFFFFF.
+ * @param[out] pOut square root of input value.
+ * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if
+ * in
is negative value and returns zero output for negative values.
+ */
+ arm_status arm_sqrt_q31(
+ q31_t in,
+ q31_t * pOut);
+
+
+ /**
+ * @brief Q15 square root function.
+ * @param[in] in input value. The range of the input value is [0 +1) or 0x0000 to 0x7FFF.
+ * @param[out] pOut square root of input value.
+ * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if
+ * in
is negative value and returns zero output for negative values.
+ */
+ arm_status arm_sqrt_q15(
+ q15_t in,
+ q15_t * pOut);
+
+ /**
+ * @} end of SQRT group
+ */
+
+
+ /**
+ * @brief floating-point Circular write function.
+ */
+ static __INLINE void arm_circularWrite_f32(
+ int32_t * circBuffer,
+ int32_t L,
+ uint16_t * writeOffset,
+ int32_t bufferInc,
+ const int32_t * src,
+ int32_t srcInc,
+ uint32_t blockSize)
+ {
+ uint32_t i = 0u;
+ int32_t wOffset;
+
+ /* Copy the value of Index pointer that points
+ * to the current location where the input samples to be copied */
+ wOffset = *writeOffset;
+
+ /* Loop over the blockSize */
+ i = blockSize;
+
+ while(i > 0u)
+ {
+ /* copy the input sample to the circular buffer */
+ circBuffer[wOffset] = *src;
+
+ /* Update the input pointer */
+ src += srcInc;
+
+ /* Circularly update wOffset. Watch out for positive and negative value */
+ wOffset += bufferInc;
+ if(wOffset >= L)
+ wOffset -= L;
+
+ /* Decrement the loop counter */
+ i--;
+ }
+
+ /* Update the index pointer */
+ *writeOffset = (uint16_t)wOffset;
+ }
+
+
+
+ /**
+ * @brief floating-point Circular Read function.
+ */
+ static __INLINE void arm_circularRead_f32(
+ int32_t * circBuffer,
+ int32_t L,
+ int32_t * readOffset,
+ int32_t bufferInc,
+ int32_t * dst,
+ int32_t * dst_base,
+ int32_t dst_length,
+ int32_t dstInc,
+ uint32_t blockSize)
+ {
+ uint32_t i = 0u;
+ int32_t rOffset, dst_end;
+
+ /* Copy the value of Index pointer that points
+ * to the current location from where the input samples to be read */
+ rOffset = *readOffset;
+ dst_end = (int32_t) (dst_base + dst_length);
+
+ /* Loop over the blockSize */
+ i = blockSize;
+
+ while(i > 0u)
+ {
+ /* copy the sample from the circular buffer to the destination buffer */
+ *dst = circBuffer[rOffset];
+
+ /* Update the input pointer */
+ dst += dstInc;
+
+ if(dst == (int32_t *) dst_end)
+ {
+ dst = dst_base;
+ }
+
+ /* Circularly update rOffset. Watch out for positive and negative value */
+ rOffset += bufferInc;
+
+ if(rOffset >= L)
+ {
+ rOffset -= L;
+ }
+
+ /* Decrement the loop counter */
+ i--;
+ }
+
+ /* Update the index pointer */
+ *readOffset = rOffset;
+ }
+
+
+ /**
+ * @brief Q15 Circular write function.
+ */
+ static __INLINE void arm_circularWrite_q15(
+ q15_t * circBuffer,
+ int32_t L,
+ uint16_t * writeOffset,
+ int32_t bufferInc,
+ const q15_t * src,
+ int32_t srcInc,
+ uint32_t blockSize)
+ {
+ uint32_t i = 0u;
+ int32_t wOffset;
+
+ /* Copy the value of Index pointer that points
+ * to the current location where the input samples to be copied */
+ wOffset = *writeOffset;
+
+ /* Loop over the blockSize */
+ i = blockSize;
+
+ while(i > 0u)
+ {
+ /* copy the input sample to the circular buffer */
+ circBuffer[wOffset] = *src;
+
+ /* Update the input pointer */
+ src += srcInc;
+
+ /* Circularly update wOffset. Watch out for positive and negative value */
+ wOffset += bufferInc;
+ if(wOffset >= L)
+ wOffset -= L;
+
+ /* Decrement the loop counter */
+ i--;
+ }
+
+ /* Update the index pointer */
+ *writeOffset = (uint16_t)wOffset;
+ }
+
+
+ /**
+ * @brief Q15 Circular Read function.
+ */
+ static __INLINE void arm_circularRead_q15(
+ q15_t * circBuffer,
+ int32_t L,
+ int32_t * readOffset,
+ int32_t bufferInc,
+ q15_t * dst,
+ q15_t * dst_base,
+ int32_t dst_length,
+ int32_t dstInc,
+ uint32_t blockSize)
+ {
+ uint32_t i = 0;
+ int32_t rOffset, dst_end;
+
+ /* Copy the value of Index pointer that points
+ * to the current location from where the input samples to be read */
+ rOffset = *readOffset;
+
+ dst_end = (int32_t) (dst_base + dst_length);
+
+ /* Loop over the blockSize */
+ i = blockSize;
+
+ while(i > 0u)
+ {
+ /* copy the sample from the circular buffer to the destination buffer */
+ *dst = circBuffer[rOffset];
+
+ /* Update the input pointer */
+ dst += dstInc;
+
+ if(dst == (q15_t *) dst_end)
+ {
+ dst = dst_base;
+ }
+
+ /* Circularly update wOffset. Watch out for positive and negative value */
+ rOffset += bufferInc;
+
+ if(rOffset >= L)
+ {
+ rOffset -= L;
+ }
+
+ /* Decrement the loop counter */
+ i--;
+ }
+
+ /* Update the index pointer */
+ *readOffset = rOffset;
+ }
+
+
+ /**
+ * @brief Q7 Circular write function.
+ */
+ static __INLINE void arm_circularWrite_q7(
+ q7_t * circBuffer,
+ int32_t L,
+ uint16_t * writeOffset,
+ int32_t bufferInc,
+ const q7_t * src,
+ int32_t srcInc,
+ uint32_t blockSize)
+ {
+ uint32_t i = 0u;
+ int32_t wOffset;
+
+ /* Copy the value of Index pointer that points
+ * to the current location where the input samples to be copied */
+ wOffset = *writeOffset;
+
+ /* Loop over the blockSize */
+ i = blockSize;
+
+ while(i > 0u)
+ {
+ /* copy the input sample to the circular buffer */
+ circBuffer[wOffset] = *src;
+
+ /* Update the input pointer */
+ src += srcInc;
+
+ /* Circularly update wOffset. Watch out for positive and negative value */
+ wOffset += bufferInc;
+ if(wOffset >= L)
+ wOffset -= L;
+
+ /* Decrement the loop counter */
+ i--;
+ }
+
+ /* Update the index pointer */
+ *writeOffset = (uint16_t)wOffset;
+ }
+
+
+ /**
+ * @brief Q7 Circular Read function.
+ */
+ static __INLINE void arm_circularRead_q7(
+ q7_t * circBuffer,
+ int32_t L,
+ int32_t * readOffset,
+ int32_t bufferInc,
+ q7_t * dst,
+ q7_t * dst_base,
+ int32_t dst_length,
+ int32_t dstInc,
+ uint32_t blockSize)
+ {
+ uint32_t i = 0;
+ int32_t rOffset, dst_end;
+
+ /* Copy the value of Index pointer that points
+ * to the current location from where the input samples to be read */
+ rOffset = *readOffset;
+
+ dst_end = (int32_t) (dst_base + dst_length);
+
+ /* Loop over the blockSize */
+ i = blockSize;
+
+ while(i > 0u)
+ {
+ /* copy the sample from the circular buffer to the destination buffer */
+ *dst = circBuffer[rOffset];
+
+ /* Update the input pointer */
+ dst += dstInc;
+
+ if(dst == (q7_t *) dst_end)
+ {
+ dst = dst_base;
+ }
+
+ /* Circularly update rOffset. Watch out for positive and negative value */
+ rOffset += bufferInc;
+
+ if(rOffset >= L)
+ {
+ rOffset -= L;
+ }
+
+ /* Decrement the loop counter */
+ i--;
+ }
+
+ /* Update the index pointer */
+ *readOffset = rOffset;
+ }
+
+
+ /**
+ * @brief Sum of the squares of the elements of a Q31 vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output value.
+ */
+ void arm_power_q31(
+ q31_t * pSrc,
+ uint32_t blockSize,
+ q63_t * pResult);
+
+
+ /**
+ * @brief Sum of the squares of the elements of a floating-point vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output value.
+ */
+ void arm_power_f32(
+ float32_t * pSrc,
+ uint32_t blockSize,
+ float32_t * pResult);
+
+
+ /**
+ * @brief Sum of the squares of the elements of a Q15 vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output value.
+ */
+ void arm_power_q15(
+ q15_t * pSrc,
+ uint32_t blockSize,
+ q63_t * pResult);
+
+
+ /**
+ * @brief Sum of the squares of the elements of a Q7 vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output value.
+ */
+ void arm_power_q7(
+ q7_t * pSrc,
+ uint32_t blockSize,
+ q31_t * pResult);
+
+
+ /**
+ * @brief Mean value of a Q7 vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output value.
+ */
+ void arm_mean_q7(
+ q7_t * pSrc,
+ uint32_t blockSize,
+ q7_t * pResult);
+
+
+ /**
+ * @brief Mean value of a Q15 vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output value.
+ */
+ void arm_mean_q15(
+ q15_t * pSrc,
+ uint32_t blockSize,
+ q15_t * pResult);
+
+
+ /**
+ * @brief Mean value of a Q31 vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output value.
+ */
+ void arm_mean_q31(
+ q31_t * pSrc,
+ uint32_t blockSize,
+ q31_t * pResult);
+
+
+ /**
+ * @brief Mean value of a floating-point vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output value.
+ */
+ void arm_mean_f32(
+ float32_t * pSrc,
+ uint32_t blockSize,
+ float32_t * pResult);
+
+
+ /**
+ * @brief Variance of the elements of a floating-point vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output value.
+ */
+ void arm_var_f32(
+ float32_t * pSrc,
+ uint32_t blockSize,
+ float32_t * pResult);
+
+
+ /**
+ * @brief Variance of the elements of a Q31 vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output value.
+ */
+ void arm_var_q31(
+ q31_t * pSrc,
+ uint32_t blockSize,
+ q31_t * pResult);
+
+
+ /**
+ * @brief Variance of the elements of a Q15 vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output value.
+ */
+ void arm_var_q15(
+ q15_t * pSrc,
+ uint32_t blockSize,
+ q15_t * pResult);
+
+
+ /**
+ * @brief Root Mean Square of the elements of a floating-point vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output value.
+ */
+ void arm_rms_f32(
+ float32_t * pSrc,
+ uint32_t blockSize,
+ float32_t * pResult);
+
+
+ /**
+ * @brief Root Mean Square of the elements of a Q31 vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output value.
+ */
+ void arm_rms_q31(
+ q31_t * pSrc,
+ uint32_t blockSize,
+ q31_t * pResult);
+
+
+ /**
+ * @brief Root Mean Square of the elements of a Q15 vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output value.
+ */
+ void arm_rms_q15(
+ q15_t * pSrc,
+ uint32_t blockSize,
+ q15_t * pResult);
+
+
+ /**
+ * @brief Standard deviation of the elements of a floating-point vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output value.
+ */
+ void arm_std_f32(
+ float32_t * pSrc,
+ uint32_t blockSize,
+ float32_t * pResult);
+
+
+ /**
+ * @brief Standard deviation of the elements of a Q31 vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output value.
+ */
+ void arm_std_q31(
+ q31_t * pSrc,
+ uint32_t blockSize,
+ q31_t * pResult);
+
+
+ /**
+ * @brief Standard deviation of the elements of a Q15 vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output value.
+ */
+ void arm_std_q15(
+ q15_t * pSrc,
+ uint32_t blockSize,
+ q15_t * pResult);
+
+
+ /**
+ * @brief Floating-point complex magnitude
+ * @param[in] pSrc points to the complex input vector
+ * @param[out] pDst points to the real output vector
+ * @param[in] numSamples number of complex samples in the input vector
+ */
+ void arm_cmplx_mag_f32(
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t numSamples);
+
+
+ /**
+ * @brief Q31 complex magnitude
+ * @param[in] pSrc points to the complex input vector
+ * @param[out] pDst points to the real output vector
+ * @param[in] numSamples number of complex samples in the input vector
+ */
+ void arm_cmplx_mag_q31(
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t numSamples);
+
+
+ /**
+ * @brief Q15 complex magnitude
+ * @param[in] pSrc points to the complex input vector
+ * @param[out] pDst points to the real output vector
+ * @param[in] numSamples number of complex samples in the input vector
+ */
+ void arm_cmplx_mag_q15(
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t numSamples);
+
+
+ /**
+ * @brief Q15 complex dot product
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[in] numSamples number of complex samples in each vector
+ * @param[out] realResult real part of the result returned here
+ * @param[out] imagResult imaginary part of the result returned here
+ */
+ void arm_cmplx_dot_prod_q15(
+ q15_t * pSrcA,
+ q15_t * pSrcB,
+ uint32_t numSamples,
+ q31_t * realResult,
+ q31_t * imagResult);
+
+
+ /**
+ * @brief Q31 complex dot product
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[in] numSamples number of complex samples in each vector
+ * @param[out] realResult real part of the result returned here
+ * @param[out] imagResult imaginary part of the result returned here
+ */
+ void arm_cmplx_dot_prod_q31(
+ q31_t * pSrcA,
+ q31_t * pSrcB,
+ uint32_t numSamples,
+ q63_t * realResult,
+ q63_t * imagResult);
+
+
+ /**
+ * @brief Floating-point complex dot product
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[in] numSamples number of complex samples in each vector
+ * @param[out] realResult real part of the result returned here
+ * @param[out] imagResult imaginary part of the result returned here
+ */
+ void arm_cmplx_dot_prod_f32(
+ float32_t * pSrcA,
+ float32_t * pSrcB,
+ uint32_t numSamples,
+ float32_t * realResult,
+ float32_t * imagResult);
+
+
+ /**
+ * @brief Q15 complex-by-real multiplication
+ * @param[in] pSrcCmplx points to the complex input vector
+ * @param[in] pSrcReal points to the real input vector
+ * @param[out] pCmplxDst points to the complex output vector
+ * @param[in] numSamples number of samples in each vector
+ */
+ void arm_cmplx_mult_real_q15(
+ q15_t * pSrcCmplx,
+ q15_t * pSrcReal,
+ q15_t * pCmplxDst,
+ uint32_t numSamples);
+
+
+ /**
+ * @brief Q31 complex-by-real multiplication
+ * @param[in] pSrcCmplx points to the complex input vector
+ * @param[in] pSrcReal points to the real input vector
+ * @param[out] pCmplxDst points to the complex output vector
+ * @param[in] numSamples number of samples in each vector
+ */
+ void arm_cmplx_mult_real_q31(
+ q31_t * pSrcCmplx,
+ q31_t * pSrcReal,
+ q31_t * pCmplxDst,
+ uint32_t numSamples);
+
+
+ /**
+ * @brief Floating-point complex-by-real multiplication
+ * @param[in] pSrcCmplx points to the complex input vector
+ * @param[in] pSrcReal points to the real input vector
+ * @param[out] pCmplxDst points to the complex output vector
+ * @param[in] numSamples number of samples in each vector
+ */
+ void arm_cmplx_mult_real_f32(
+ float32_t * pSrcCmplx,
+ float32_t * pSrcReal,
+ float32_t * pCmplxDst,
+ uint32_t numSamples);
+
+
+ /**
+ * @brief Minimum value of a Q7 vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] result is output pointer
+ * @param[in] index is the array index of the minimum value in the input buffer.
+ */
+ void arm_min_q7(
+ q7_t * pSrc,
+ uint32_t blockSize,
+ q7_t * result,
+ uint32_t * index);
+
+
+ /**
+ * @brief Minimum value of a Q15 vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output pointer
+ * @param[in] pIndex is the array index of the minimum value in the input buffer.
+ */
+ void arm_min_q15(
+ q15_t * pSrc,
+ uint32_t blockSize,
+ q15_t * pResult,
+ uint32_t * pIndex);
+
+
+ /**
+ * @brief Minimum value of a Q31 vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output pointer
+ * @param[out] pIndex is the array index of the minimum value in the input buffer.
+ */
+ void arm_min_q31(
+ q31_t * pSrc,
+ uint32_t blockSize,
+ q31_t * pResult,
+ uint32_t * pIndex);
+
+
+ /**
+ * @brief Minimum value of a floating-point vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output pointer
+ * @param[out] pIndex is the array index of the minimum value in the input buffer.
+ */
+ void arm_min_f32(
+ float32_t * pSrc,
+ uint32_t blockSize,
+ float32_t * pResult,
+ uint32_t * pIndex);
+
+
+/**
+ * @brief Maximum value of a Q7 vector.
+ * @param[in] pSrc points to the input buffer
+ * @param[in] blockSize length of the input vector
+ * @param[out] pResult maximum value returned here
+ * @param[out] pIndex index of maximum value returned here
+ */
+ void arm_max_q7(
+ q7_t * pSrc,
+ uint32_t blockSize,
+ q7_t * pResult,
+ uint32_t * pIndex);
+
+
+/**
+ * @brief Maximum value of a Q15 vector.
+ * @param[in] pSrc points to the input buffer
+ * @param[in] blockSize length of the input vector
+ * @param[out] pResult maximum value returned here
+ * @param[out] pIndex index of maximum value returned here
+ */
+ void arm_max_q15(
+ q15_t * pSrc,
+ uint32_t blockSize,
+ q15_t * pResult,
+ uint32_t * pIndex);
+
+
+/**
+ * @brief Maximum value of a Q31 vector.
+ * @param[in] pSrc points to the input buffer
+ * @param[in] blockSize length of the input vector
+ * @param[out] pResult maximum value returned here
+ * @param[out] pIndex index of maximum value returned here
+ */
+ void arm_max_q31(
+ q31_t * pSrc,
+ uint32_t blockSize,
+ q31_t * pResult,
+ uint32_t * pIndex);
+
+
+/**
+ * @brief Maximum value of a floating-point vector.
+ * @param[in] pSrc points to the input buffer
+ * @param[in] blockSize length of the input vector
+ * @param[out] pResult maximum value returned here
+ * @param[out] pIndex index of maximum value returned here
+ */
+ void arm_max_f32(
+ float32_t * pSrc,
+ uint32_t blockSize,
+ float32_t * pResult,
+ uint32_t * pIndex);
+
+
+ /**
+ * @brief Q15 complex-by-complex multiplication
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] numSamples number of complex samples in each vector
+ */
+ void arm_cmplx_mult_cmplx_q15(
+ q15_t * pSrcA,
+ q15_t * pSrcB,
+ q15_t * pDst,
+ uint32_t numSamples);
+
+
+ /**
+ * @brief Q31 complex-by-complex multiplication
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] numSamples number of complex samples in each vector
+ */
+ void arm_cmplx_mult_cmplx_q31(
+ q31_t * pSrcA,
+ q31_t * pSrcB,
+ q31_t * pDst,
+ uint32_t numSamples);
+
+
+ /**
+ * @brief Floating-point complex-by-complex multiplication
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] numSamples number of complex samples in each vector
+ */
+ void arm_cmplx_mult_cmplx_f32(
+ float32_t * pSrcA,
+ float32_t * pSrcB,
+ float32_t * pDst,
+ uint32_t numSamples);
+
+
+ /**
+ * @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
+ */
+ void arm_float_to_q31(
+ float32_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @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
+ */
+ void arm_float_to_q15(
+ float32_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @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
+ */
+ void arm_float_to_q7(
+ float32_t * pSrc,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Converts the elements of the Q31 vector to Q15 vector.
+ * @param[in] pSrc is input pointer
+ * @param[out] pDst is output pointer
+ * @param[in] blockSize is the number of samples to process
+ */
+ void arm_q31_to_q15(
+ q31_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Converts the elements of the Q31 vector to Q7 vector.
+ * @param[in] pSrc is input pointer
+ * @param[out] pDst is output pointer
+ * @param[in] blockSize is the number of samples to process
+ */
+ void arm_q31_to_q7(
+ q31_t * pSrc,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Converts the elements of the Q15 vector to floating-point vector.
+ * @param[in] pSrc is input pointer
+ * @param[out] pDst is output pointer
+ * @param[in] blockSize is the number of samples to process
+ */
+ void arm_q15_to_float(
+ q15_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Converts the elements of the Q15 vector to Q31 vector.
+ * @param[in] pSrc is input pointer
+ * @param[out] pDst is output pointer
+ * @param[in] blockSize is the number of samples to process
+ */
+ void arm_q15_to_q31(
+ q15_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Converts the elements of the Q15 vector to Q7 vector.
+ * @param[in] pSrc is input pointer
+ * @param[out] pDst is output pointer
+ * @param[in] blockSize is the number of samples to process
+ */
+ void arm_q15_to_q7(
+ q15_t * pSrc,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @ingroup groupInterpolation
+ */
+
+ /**
+ * @defgroup BilinearInterpolate Bilinear Interpolation
+ *
+ * Bilinear interpolation is an extension of linear interpolation applied to a two dimensional grid.
+ * The underlying function f(x, y)
is sampled on a regular grid and the interpolation process
+ * determines values between the grid points.
+ * Bilinear interpolation is equivalent to two step linear interpolation, first in the x-dimension and then in the y-dimension.
+ * Bilinear interpolation is often used in image processing to rescale images.
+ * The CMSIS DSP library provides bilinear interpolation functions for Q7, Q15, Q31, and floating-point data types.
+ *
+ * Algorithm
+ * \par
+ * The instance structure used by the bilinear interpolation functions describes a two dimensional data table.
+ * For floating-point, the instance structure is defined as:
+ *
+ * typedef struct
+ * {
+ * uint16_t numRows;
+ * uint16_t numCols;
+ * float32_t *pData;
+ * } arm_bilinear_interp_instance_f32;
+ *
+ *
+ * \par
+ * where numRows
specifies the number of rows in the table;
+ * numCols
specifies the number of columns in the table;
+ * and pData
points to an array of size numRows*numCols
values.
+ * The data table pTable
is organized in row order and the supplied data values fall on integer indexes.
+ * That is, table element (x,y) is located at pTable[x + y*numCols]
where x and y are integers.
+ *
+ * \par
+ * Let (x, y)
specify the desired interpolation point. Then define:
+ *
+ * XF = floor(x)
+ * YF = floor(y)
+ *
+ * \par
+ * The interpolated output point is computed as:
+ *
+ * f(x, y) = f(XF, YF) * (1-(x-XF)) * (1-(y-YF))
+ * + f(XF+1, YF) * (x-XF)*(1-(y-YF))
+ * + f(XF, YF+1) * (1-(x-XF))*(y-YF)
+ * + f(XF+1, YF+1) * (x-XF)*(y-YF)
+ *
+ * Note that the coordinates (x, y) contain integer and fractional components.
+ * The integer components specify which portion of the table to use while the
+ * fractional components control the interpolation processor.
+ *
+ * \par
+ * if (x,y) are outside of the table boundary, Bilinear interpolation returns zero output.
+ */
+
+ /**
+ * @addtogroup BilinearInterpolate
+ * @{
+ */
+
+
+ /**
+ *
+ * @brief Floating-point bilinear interpolation.
+ * @param[in,out] S points to an instance of the interpolation structure.
+ * @param[in] X interpolation coordinate.
+ * @param[in] Y interpolation coordinate.
+ * @return out interpolated value.
+ */
+ static __INLINE float32_t arm_bilinear_interp_f32(
+ const arm_bilinear_interp_instance_f32 * S,
+ float32_t X,
+ float32_t Y)
+ {
+ float32_t out;
+ float32_t f00, f01, f10, f11;
+ float32_t *pData = S->pData;
+ int32_t xIndex, yIndex, index;
+ float32_t xdiff, ydiff;
+ float32_t b1, b2, b3, b4;
+
+ xIndex = (int32_t) X;
+ yIndex = (int32_t) Y;
+
+ /* Care taken for table outside boundary */
+ /* Returns zero output when values are outside table boundary */
+ if(xIndex < 0 || xIndex > (S->numRows - 1) || yIndex < 0 || yIndex > (S->numCols - 1))
+ {
+ return (0);
+ }
+
+ /* Calculation of index for two nearest points in X-direction */
+ index = (xIndex - 1) + (yIndex - 1) * S->numCols;
+
+
+ /* Read two nearest points in X-direction */
+ f00 = pData[index];
+ f01 = pData[index + 1];
+
+ /* Calculation of index for two nearest points in Y-direction */
+ index = (xIndex - 1) + (yIndex) * S->numCols;
+
+
+ /* Read two nearest points in Y-direction */
+ f10 = pData[index];
+ f11 = pData[index + 1];
+
+ /* Calculation of intermediate values */
+ b1 = f00;
+ b2 = f01 - f00;
+ b3 = f10 - f00;
+ b4 = f00 - f01 - f10 + f11;
+
+ /* Calculation of fractional part in X */
+ xdiff = X - xIndex;
+
+ /* Calculation of fractional part in Y */
+ ydiff = Y - yIndex;
+
+ /* Calculation of bi-linear interpolated output */
+ out = b1 + b2 * xdiff + b3 * ydiff + b4 * xdiff * ydiff;
+
+ /* return to application */
+ return (out);
+ }
+
+
+ /**
+ *
+ * @brief Q31 bilinear interpolation.
+ * @param[in,out] S points to an instance of the interpolation structure.
+ * @param[in] X interpolation coordinate in 12.20 format.
+ * @param[in] Y interpolation coordinate in 12.20 format.
+ * @return out interpolated value.
+ */
+ static __INLINE q31_t arm_bilinear_interp_q31(
+ arm_bilinear_interp_instance_q31 * S,
+ q31_t X,
+ q31_t Y)
+ {
+ q31_t out; /* Temporary output */
+ q31_t acc = 0; /* output */
+ q31_t xfract, yfract; /* X, Y fractional parts */
+ q31_t x1, x2, y1, y2; /* Nearest output values */
+ int32_t rI, cI; /* Row and column indices */
+ q31_t *pYData = S->pData; /* pointer to output table values */
+ uint32_t nCols = S->numCols; /* num of rows */
+
+ /* Input is in 12.20 format */
+ /* 12 bits for the table index */
+ /* Index value calculation */
+ rI = ((X & (q31_t)0xFFF00000) >> 20);
+
+ /* Input is in 12.20 format */
+ /* 12 bits for the table index */
+ /* Index value calculation */
+ cI = ((Y & (q31_t)0xFFF00000) >> 20);
+
+ /* Care taken for table outside boundary */
+ /* Returns zero output when values are outside table boundary */
+ if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1))
+ {
+ return (0);
+ }
+
+ /* 20 bits for the fractional part */
+ /* shift left xfract by 11 to keep 1.31 format */
+ xfract = (X & 0x000FFFFF) << 11u;
+
+ /* Read two nearest output values from the index */
+ x1 = pYData[(rI) + (int32_t)nCols * (cI) ];
+ x2 = pYData[(rI) + (int32_t)nCols * (cI) + 1];
+
+ /* 20 bits for the fractional part */
+ /* shift left yfract by 11 to keep 1.31 format */
+ yfract = (Y & 0x000FFFFF) << 11u;
+
+ /* Read two nearest output values from the index */
+ y1 = pYData[(rI) + (int32_t)nCols * (cI + 1) ];
+ y2 = pYData[(rI) + (int32_t)nCols * (cI + 1) + 1];
+
+ /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 3.29(q29) format */
+ out = ((q31_t) (((q63_t) x1 * (0x7FFFFFFF - xfract)) >> 32));
+ acc = ((q31_t) (((q63_t) out * (0x7FFFFFFF - yfract)) >> 32));
+
+ /* x2 * (xfract) * (1-yfract) in 3.29(q29) and adding to acc */
+ out = ((q31_t) ((q63_t) x2 * (0x7FFFFFFF - yfract) >> 32));
+ acc += ((q31_t) ((q63_t) out * (xfract) >> 32));
+
+ /* y1 * (1 - xfract) * (yfract) in 3.29(q29) and adding to acc */
+ out = ((q31_t) ((q63_t) y1 * (0x7FFFFFFF - xfract) >> 32));
+ acc += ((q31_t) ((q63_t) out * (yfract) >> 32));
+
+ /* y2 * (xfract) * (yfract) in 3.29(q29) and adding to acc */
+ out = ((q31_t) ((q63_t) y2 * (xfract) >> 32));
+ acc += ((q31_t) ((q63_t) out * (yfract) >> 32));
+
+ /* Convert acc to 1.31(q31) format */
+ return ((q31_t)(acc << 2));
+ }
+
+
+ /**
+ * @brief Q15 bilinear interpolation.
+ * @param[in,out] S points to an instance of the interpolation structure.
+ * @param[in] X interpolation coordinate in 12.20 format.
+ * @param[in] Y interpolation coordinate in 12.20 format.
+ * @return out interpolated value.
+ */
+ static __INLINE q15_t arm_bilinear_interp_q15(
+ arm_bilinear_interp_instance_q15 * S,
+ q31_t X,
+ q31_t Y)
+ {
+ q63_t acc = 0; /* output */
+ q31_t out; /* Temporary output */
+ q15_t x1, x2, y1, y2; /* Nearest output values */
+ q31_t xfract, yfract; /* X, Y fractional parts */
+ int32_t rI, cI; /* Row and column indices */
+ q15_t *pYData = S->pData; /* pointer to output table values */
+ uint32_t nCols = S->numCols; /* num of rows */
+
+ /* Input is in 12.20 format */
+ /* 12 bits for the table index */
+ /* Index value calculation */
+ rI = ((X & (q31_t)0xFFF00000) >> 20);
+
+ /* Input is in 12.20 format */
+ /* 12 bits for the table index */
+ /* Index value calculation */
+ cI = ((Y & (q31_t)0xFFF00000) >> 20);
+
+ /* Care taken for table outside boundary */
+ /* Returns zero output when values are outside table boundary */
+ if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1))
+ {
+ return (0);
+ }
+
+ /* 20 bits for the fractional part */
+ /* xfract should be in 12.20 format */
+ xfract = (X & 0x000FFFFF);
+
+ /* Read two nearest output values from the index */
+ x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) ];
+ x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1];
+
+ /* 20 bits for the fractional part */
+ /* yfract should be in 12.20 format */
+ yfract = (Y & 0x000FFFFF);
+
+ /* Read two nearest output values from the index */
+ y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) ];
+ y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1];
+
+ /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 13.51 format */
+
+ /* x1 is in 1.15(q15), xfract in 12.20 format and out is in 13.35 format */
+ /* convert 13.35 to 13.31 by right shifting and out is in 1.31 */
+ out = (q31_t) (((q63_t) x1 * (0xFFFFF - xfract)) >> 4u);
+ acc = ((q63_t) out * (0xFFFFF - yfract));
+
+ /* x2 * (xfract) * (1-yfract) in 1.51 and adding to acc */
+ out = (q31_t) (((q63_t) x2 * (0xFFFFF - yfract)) >> 4u);
+ acc += ((q63_t) out * (xfract));
+
+ /* y1 * (1 - xfract) * (yfract) in 1.51 and adding to acc */
+ out = (q31_t) (((q63_t) y1 * (0xFFFFF - xfract)) >> 4u);
+ acc += ((q63_t) out * (yfract));
+
+ /* y2 * (xfract) * (yfract) in 1.51 and adding to acc */
+ out = (q31_t) (((q63_t) y2 * (xfract)) >> 4u);
+ acc += ((q63_t) out * (yfract));
+
+ /* acc is in 13.51 format and down shift acc by 36 times */
+ /* Convert out to 1.15 format */
+ return ((q15_t)(acc >> 36));
+ }
+
+
+ /**
+ * @brief Q7 bilinear interpolation.
+ * @param[in,out] S points to an instance of the interpolation structure.
+ * @param[in] X interpolation coordinate in 12.20 format.
+ * @param[in] Y interpolation coordinate in 12.20 format.
+ * @return out interpolated value.
+ */
+ static __INLINE q7_t arm_bilinear_interp_q7(
+ arm_bilinear_interp_instance_q7 * S,
+ q31_t X,
+ q31_t Y)
+ {
+ q63_t acc = 0; /* output */
+ q31_t out; /* Temporary output */
+ q31_t xfract, yfract; /* X, Y fractional parts */
+ q7_t x1, x2, y1, y2; /* Nearest output values */
+ int32_t rI, cI; /* Row and column indices */
+ q7_t *pYData = S->pData; /* pointer to output table values */
+ uint32_t nCols = S->numCols; /* num of rows */
+
+ /* Input is in 12.20 format */
+ /* 12 bits for the table index */
+ /* Index value calculation */
+ rI = ((X & (q31_t)0xFFF00000) >> 20);
+
+ /* Input is in 12.20 format */
+ /* 12 bits for the table index */
+ /* Index value calculation */
+ cI = ((Y & (q31_t)0xFFF00000) >> 20);
+
+ /* Care taken for table outside boundary */
+ /* Returns zero output when values are outside table boundary */
+ if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1))
+ {
+ return (0);
+ }
+
+ /* 20 bits for the fractional part */
+ /* xfract should be in 12.20 format */
+ xfract = (X & (q31_t)0x000FFFFF);
+
+ /* Read two nearest output values from the index */
+ x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) ];
+ x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1];
+
+ /* 20 bits for the fractional part */
+ /* yfract should be in 12.20 format */
+ yfract = (Y & (q31_t)0x000FFFFF);
+
+ /* Read two nearest output values from the index */
+ y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) ];
+ y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1];
+
+ /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 16.47 format */
+ out = ((x1 * (0xFFFFF - xfract)));
+ acc = (((q63_t) out * (0xFFFFF - yfract)));
+
+ /* x2 * (xfract) * (1-yfract) in 2.22 and adding to acc */
+ out = ((x2 * (0xFFFFF - yfract)));
+ acc += (((q63_t) out * (xfract)));
+
+ /* y1 * (1 - xfract) * (yfract) in 2.22 and adding to acc */
+ out = ((y1 * (0xFFFFF - xfract)));
+ acc += (((q63_t) out * (yfract)));
+
+ /* y2 * (xfract) * (yfract) in 2.22 and adding to acc */
+ out = ((y2 * (yfract)));
+ acc += (((q63_t) out * (xfract)));
+
+ /* acc in 16.47 format and down shift by 40 to convert to 1.7 format */
+ return ((q7_t)(acc >> 40));
+ }
+
+ /**
+ * @} end of BilinearInterpolate group
+ */
+
+
+/* SMMLAR */
+#define multAcc_32x32_keep32_R(a, x, y) \
+ a = (q31_t) (((((q63_t) a) << 32) + ((q63_t) x * y) + 0x80000000LL ) >> 32)
+
+/* SMMLSR */
+#define multSub_32x32_keep32_R(a, x, y) \
+ a = (q31_t) (((((q63_t) a) << 32) - ((q63_t) x * y) + 0x80000000LL ) >> 32)
+
+/* SMMULR */
+#define mult_32x32_keep32_R(a, x, y) \
+ a = (q31_t) (((q63_t) x * y + 0x80000000LL ) >> 32)
+
+/* SMMLA */
+#define multAcc_32x32_keep32(a, x, y) \
+ a += (q31_t) (((q63_t) x * y) >> 32)
+
+/* SMMLS */
+#define multSub_32x32_keep32(a, x, y) \
+ a -= (q31_t) (((q63_t) x * y) >> 32)
+
+/* SMMUL */
+#define mult_32x32_keep32(a, x, y) \
+ a = (q31_t) (((q63_t) x * y ) >> 32)
+
+
+#if defined ( __CC_ARM )
+ /* Enter low optimization region - place directly above function definition */
+ #if defined( ARM_MATH_CM4 ) || defined( ARM_MATH_CM7)
+ #define LOW_OPTIMIZATION_ENTER \
+ _Pragma ("push") \
+ _Pragma ("O1")
+ #else
+ #define LOW_OPTIMIZATION_ENTER
+ #endif
+
+ /* Exit low optimization region - place directly after end of function definition */
+ #if defined( ARM_MATH_CM4 ) || defined( ARM_MATH_CM7)
+ #define LOW_OPTIMIZATION_EXIT \
+ _Pragma ("pop")
+ #else
+ #define LOW_OPTIMIZATION_EXIT
+ #endif
+
+ /* Enter low optimization region - place directly above function definition */
+ #define IAR_ONLY_LOW_OPTIMIZATION_ENTER
+
+ /* Exit low optimization region - place directly after end of function definition */
+ #define IAR_ONLY_LOW_OPTIMIZATION_EXIT
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #define LOW_OPTIMIZATION_ENTER
+ #define LOW_OPTIMIZATION_EXIT
+ #define IAR_ONLY_LOW_OPTIMIZATION_ENTER
+ #define IAR_ONLY_LOW_OPTIMIZATION_EXIT
+
+#elif defined(__GNUC__)
+ #define LOW_OPTIMIZATION_ENTER __attribute__(( optimize("-O1") ))
+ #define LOW_OPTIMIZATION_EXIT
+ #define IAR_ONLY_LOW_OPTIMIZATION_ENTER
+ #define IAR_ONLY_LOW_OPTIMIZATION_EXIT
+
+#elif defined(__ICCARM__)
+ /* Enter low optimization region - place directly above function definition */
+ #if defined( ARM_MATH_CM4 ) || defined( ARM_MATH_CM7)
+ #define LOW_OPTIMIZATION_ENTER \
+ _Pragma ("optimize=low")
+ #else
+ #define LOW_OPTIMIZATION_ENTER
+ #endif
+
+ /* Exit low optimization region - place directly after end of function definition */
+ #define LOW_OPTIMIZATION_EXIT
+
+ /* Enter low optimization region - place directly above function definition */
+ #if defined( ARM_MATH_CM4 ) || defined( ARM_MATH_CM7)
+ #define IAR_ONLY_LOW_OPTIMIZATION_ENTER \
+ _Pragma ("optimize=low")
+ #else
+ #define IAR_ONLY_LOW_OPTIMIZATION_ENTER
+ #endif
+
+ /* Exit low optimization region - place directly after end of function definition */
+ #define IAR_ONLY_LOW_OPTIMIZATION_EXIT
+
+#elif defined(__CSMC__)
+ #define LOW_OPTIMIZATION_ENTER
+ #define LOW_OPTIMIZATION_EXIT
+ #define IAR_ONLY_LOW_OPTIMIZATION_ENTER
+ #define IAR_ONLY_LOW_OPTIMIZATION_EXIT
+
+#elif defined(__TASKING__)
+ #define LOW_OPTIMIZATION_ENTER
+ #define LOW_OPTIMIZATION_EXIT
+ #define IAR_ONLY_LOW_OPTIMIZATION_ENTER
+ #define IAR_ONLY_LOW_OPTIMIZATION_EXIT
+
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#if defined ( __GNUC__ )
+#pragma GCC diagnostic pop
+#endif
+
+#endif /* _ARM_MATH_H */
+
+/**
+ *
+ * End of file.
+ */
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/CM0/Core/cmsis_armcc.h b/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/CM0/Core/cmsis_armcc.h
new file mode 100644
index 0000000..74c49c6
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/CM0/Core/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/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/CM0/Core/cmsis_armcc_V6.h b/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/CM0/Core/cmsis_armcc_V6.h
new file mode 100644
index 0000000..cd13240
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/CM0/Core/cmsis_armcc_V6.h
@@ -0,0 +1,1800 @@
+/**************************************************************************//**
+ * @file cmsis_armcc_V6.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_V6_H
+#define __CMSIS_ARMCC_V6_H
+
+
+/* ########################### 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);
+}
+
+
+#if (__ARM_FEATURE_CMSE == 3U)
+/**
+ \brief Get Control Register (non-secure)
+ \details Returns the content of the non-secure Control Register when in secure mode.
+ \return non-secure Control Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_CONTROL_NS(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, control_ns" : "=r" (result) );
+ return(result);
+}
+#endif
+
+
+/**
+ \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");
+}
+
+
+#if (__ARM_FEATURE_CMSE == 3U)
+/**
+ \brief Set Control Register (non-secure)
+ \details Writes the given value to the non-secure Control Register when in secure state.
+ \param [in] control Control Register value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_CONTROL_NS(uint32_t control)
+{
+ __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory");
+}
+#endif
+
+
+/**
+ \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);
+}
+
+
+#if (__ARM_FEATURE_CMSE == 3U)
+/**
+ \brief Get IPSR Register (non-secure)
+ \details Returns the content of the non-secure IPSR Register when in secure state.
+ \return IPSR Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_IPSR_NS(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, ipsr_ns" : "=r" (result) );
+ return(result);
+}
+#endif
+
+
+/**
+ \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);
+}
+
+
+#if (__ARM_FEATURE_CMSE == 3U)
+/**
+ \brief Get APSR Register (non-secure)
+ \details Returns the content of the non-secure APSR Register when in secure state.
+ \return APSR Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_APSR_NS(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, apsr_ns" : "=r" (result) );
+ return(result);
+}
+#endif
+
+
+/**
+ \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);
+}
+
+
+#if (__ARM_FEATURE_CMSE == 3U)
+/**
+ \brief Get xPSR Register (non-secure)
+ \details Returns the content of the non-secure xPSR Register when in secure state.
+ \return xPSR Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_xPSR_NS(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, xpsr_ns" : "=r" (result) );
+ return(result);
+}
+#endif
+
+
+/**
+ \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" : "=r" (result) );
+ return(result);
+}
+
+
+#if (__ARM_FEATURE_CMSE == 3U)
+/**
+ \brief Get Process Stack Pointer (non-secure)
+ \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state.
+ \return PSP Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_PSP_NS(void)
+{
+ register uint32_t result;
+
+ __ASM volatile ("MRS %0, psp_ns" : "=r" (result) );
+ return(result);
+}
+#endif
+
+
+/**
+ \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" : : "r" (topOfProcStack) : "sp");
+}
+
+
+#if (__ARM_FEATURE_CMSE == 3U)
+/**
+ \brief Set Process Stack Pointer (non-secure)
+ \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state.
+ \param [in] topOfProcStack Process Stack Pointer value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack)
+{
+ __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : "sp");
+}
+#endif
+
+
+/**
+ \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" : "=r" (result) );
+ return(result);
+}
+
+
+#if (__ARM_FEATURE_CMSE == 3U)
+/**
+ \brief Get Main Stack Pointer (non-secure)
+ \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state.
+ \return MSP Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_MSP_NS(void)
+{
+ register uint32_t result;
+
+ __ASM volatile ("MRS %0, msp_ns" : "=r" (result) );
+ return(result);
+}
+#endif
+
+
+/**
+ \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" : : "r" (topOfMainStack) : "sp");
+}
+
+
+#if (__ARM_FEATURE_CMSE == 3U)
+/**
+ \brief Set Main Stack Pointer (non-secure)
+ \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state.
+ \param [in] topOfMainStack Main Stack Pointer value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack)
+{
+ __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : "sp");
+}
+#endif
+
+
+/**
+ \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);
+}
+
+
+#if (__ARM_FEATURE_CMSE == 3U)
+/**
+ \brief Get Priority Mask (non-secure)
+ \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state.
+ \return Priority Mask value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_PRIMASK_NS(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, primask_ns" : "=r" (result) );
+ return(result);
+}
+#endif
+
+
+/**
+ \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 (__ARM_FEATURE_CMSE == 3U)
+/**
+ \brief Set Priority Mask (non-secure)
+ \details Assigns the given value to the non-secure Priority Mask Register when in secure state.
+ \param [in] priMask Priority Mask
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PRIMASK_NS(uint32_t priMask)
+{
+ __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory");
+}
+#endif
+
+
+#if ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) /* ToDo: ARMCC_V6: check if this is ok for cortex >=3 */
+
+/**
+ \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);
+}
+
+
+#if (__ARM_FEATURE_CMSE == 3U)
+/**
+ \brief Get Base Priority (non-secure)
+ \details Returns the current value of the non-secure Base Priority register when in secure state.
+ \return Base Priority register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_BASEPRI_NS(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) );
+ return(result);
+}
+#endif
+
+
+/**
+ \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");
+}
+
+
+#if (__ARM_FEATURE_CMSE == 3U)
+/**
+ \brief Set Base Priority (non-secure)
+ \details Assigns the given value to the non-secure Base Priority register when in secure state.
+ \param [in] basePri Base Priority value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_BASEPRI_NS(uint32_t value)
+{
+ __ASM volatile ("MSR basepri_ns, %0" : : "r" (value) : "memory");
+}
+#endif
+
+
+/**
+ \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");
+}
+
+
+#if (__ARM_FEATURE_CMSE == 3U)
+/**
+ \brief Set Base Priority with condition (non_secure)
+ \details Assigns the given value to the non-secure Base Priority register when in secure state 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 __TZ_set_BASEPRI_MAX_NS(uint32_t value)
+{
+ __ASM volatile ("MSR basepri_max_ns, %0" : : "r" (value) : "memory");
+}
+#endif
+
+
+/**
+ \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);
+}
+
+
+#if (__ARM_FEATURE_CMSE == 3U)
+/**
+ \brief Get Fault Mask (non-secure)
+ \details Returns the current value of the non-secure Fault Mask register when in secure state.
+ \return Fault Mask register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_FAULTMASK_NS(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) );
+ return(result);
+}
+#endif
+
+
+/**
+ \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");
+}
+
+
+#if (__ARM_FEATURE_CMSE == 3U)
+/**
+ \brief Set Fault Mask (non-secure)
+ \details Assigns the given value to the non-secure Fault Mask register when in secure state.
+ \param [in] faultMask Fault Mask value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask)
+{
+ __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory");
+}
+#endif
+
+
+#endif /* ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_8M__ == 1U)) */
+
+
+#if (__ARM_ARCH_8M__ == 1U)
+
+/**
+ \brief Get Process Stack Pointer Limit
+ \details Returns the current value of the Process Stack Pointer Limit (PSPLIM).
+ \return PSPLIM Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_PSPLIM(void)
+{
+ register uint32_t result;
+
+ __ASM volatile ("MRS %0, psplim" : "=r" (result) );
+ return(result);
+}
+
+
+#if (__ARM_FEATURE_CMSE == 3U) && (__ARM_ARCH_PROFILE == 'M') /* ToDo: ARMCC_V6: check predefined macro for mainline */
+/**
+ \brief Get Process Stack Pointer Limit (non-secure)
+ \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state.
+ \return PSPLIM Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_PSPLIM_NS(void)
+{
+ register uint32_t result;
+
+ __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) );
+ return(result);
+}
+#endif
+
+
+/**
+ \brief Set Process Stack Pointer Limit
+ \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM).
+ \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit)
+{
+ __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit));
+}
+
+
+#if (__ARM_FEATURE_CMSE == 3U) && (__ARM_ARCH_PROFILE == 'M') /* ToDo: ARMCC_V6: check predefined macro for mainline */
+/**
+ \brief Set Process Stack Pointer (non-secure)
+ \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state.
+ \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit)
+{
+ __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit));
+}
+#endif
+
+
+/**
+ \brief Get Main Stack Pointer Limit
+ \details Returns the current value of the Main Stack Pointer Limit (MSPLIM).
+ \return MSPLIM Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_MSPLIM(void)
+{
+ register uint32_t result;
+
+ __ASM volatile ("MRS %0, msplim" : "=r" (result) );
+
+ return(result);
+}
+
+
+#if (__ARM_FEATURE_CMSE == 3U) && (__ARM_ARCH_PROFILE == 'M') /* ToDo: ARMCC_V6: check predefined macro for mainline */
+/**
+ \brief Get Main Stack Pointer Limit (non-secure)
+ \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state.
+ \return MSPLIM Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_MSPLIM_NS(void)
+{
+ register uint32_t result;
+
+ __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) );
+ return(result);
+}
+#endif
+
+
+/**
+ \brief Set Main Stack Pointer Limit
+ \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM).
+ \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __set_MSPLIM(uint32_t MainStackPtrLimit)
+{
+ __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit));
+}
+
+
+#if (__ARM_FEATURE_CMSE == 3U) && (__ARM_ARCH_PROFILE == 'M') /* ToDo: ARMCC_V6: check predefined macro for mainline */
+/**
+ \brief Set Main Stack Pointer Limit (non-secure)
+ \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state.
+ \param [in] MainStackPtrLimit Main Stack Pointer value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit)
+{
+ __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit));
+}
+#endif
+
+#endif /* (__ARM_ARCH_8M__ == 1U) */
+
+
+#if ((__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) /* ToDo: ARMCC_V6: check if this is ok for cortex >=4 */
+
+/**
+ \brief Get FPSCR
+ \details eturns the current value of the Floating Point Status/Control register.
+ \return Floating Point Status/Control register value
+ */
+#define __get_FPSCR __builtin_arm_get_fpscr
+#if 0
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_FPSCR(void)
+{
+#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
+ uint32_t result;
+
+ __ASM volatile (""); /* Empty asm statement works as a scheduling barrier */
+ __ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
+ __ASM volatile ("");
+ return(result);
+#else
+ return(0);
+#endif
+}
+#endif
+
+#if (__ARM_FEATURE_CMSE == 3U)
+/**
+ \brief Get FPSCR (non-secure)
+ \details Returns the current value of the non-secure Floating Point Status/Control register when in secure state.
+ \return Floating Point Status/Control register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_FPSCR_NS(void)
+{
+#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
+ uint32_t result;
+
+ __ASM volatile (""); /* Empty asm statement works as a scheduling barrier */
+ __ASM volatile ("VMRS %0, fpscr_ns" : "=r" (result) );
+ __ASM volatile ("");
+ return(result);
+#else
+ return(0);
+#endif
+}
+#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
+ */
+#define __set_FPSCR __builtin_arm_set_fpscr
+#if 0
+__attribute__((always_inline)) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
+{
+#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
+ __ASM volatile (""); /* Empty asm statement works as a scheduling barrier */
+ __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc");
+ __ASM volatile ("");
+#endif
+}
+#endif
+
+#if (__ARM_FEATURE_CMSE == 3U)
+/**
+ \brief Set FPSCR (non-secure)
+ \details Assigns the given value to the non-secure Floating Point Status/Control register when in secure state.
+ \param [in] fpscr Floating Point Status/Control value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_FPSCR_NS(uint32_t fpscr)
+{
+#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
+ __ASM volatile (""); /* Empty asm statement works as a scheduling barrier */
+ __ASM volatile ("VMSR fpscr_ns, %0" : : "r" (fpscr) : "vfpcc");
+ __ASM volatile ("");
+#endif
+}
+#endif
+
+#endif /* ((__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) */
+
+
+
+/*@} 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.
+ */
+#define __NOP __builtin_arm_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 __builtin_arm_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 __builtin_arm_wfe
+
+
+/**
+ \brief Send Event
+ \details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
+ */
+#define __SEV __builtin_arm_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() __builtin_arm_isb(0xF);
+
+/**
+ \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() __builtin_arm_dsb(0xF);
+
+
+/**
+ \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() __builtin_arm_dmb(0xF);
+
+
+/**
+ \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 __builtin_bswap32
+
+
+/**
+ \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
+ */
+#define __REV16 __builtin_bswap16 /* ToDo: ARMCC_V6: check if __builtin_bswap16 could be used */
+#if 0
+__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);
+}
+#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
+ */
+ /* ToDo: ARMCC_V6: check if __builtin_bswap16 could be used */
+__attribute__((always_inline)) __STATIC_INLINE int32_t __REVSH(int32_t value)
+{
+ int32_t result;
+
+ __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
+ return(result);
+}
+
+
+/**
+ \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] op1 Value to rotate
+ \param [in] op2 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
+ */
+ /* ToDo: ARMCC_V6: check if __builtin_arm_rbit is supported */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
+{
+ uint32_t result;
+
+#if ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) /* ToDo: ARMCC_V6: check if this is ok for cortex >=3 */
+ __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 ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) /* ToDo: ARMCC_V6: check if this is ok for cortex >=3 */
+
+/**
+ \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)
+ */
+#define __LDREXB (uint8_t)__builtin_arm_ldrex
+
+
+/**
+ \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)
+ */
+#define __LDREXH (uint16_t)__builtin_arm_ldrex
+
+
+/**
+ \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)
+ */
+#define __LDREXW (uint32_t)__builtin_arm_ldrex
+
+
+/**
+ \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
+ */
+#define __STREXB (uint32_t)__builtin_arm_strex
+
+
+/**
+ \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
+ */
+#define __STREXH (uint32_t)__builtin_arm_strex
+
+
+/**
+ \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
+ */
+#define __STREXW (uint32_t)__builtin_arm_strex
+
+
+/**
+ \brief Remove the exclusive lock
+ \details Removes the exclusive lock which is created by LDREX.
+ */
+#define __CLREX __builtin_arm_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 __builtin_arm_ssat*/
+#define __SSAT(ARG1,ARG2) \
+({ \
+ int32_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 __builtin_arm_usat
+#if 0
+#define __USAT(ARG1,ARG2) \
+({ \
+ uint32_t __RES, __ARG1 = (ARG1); \
+ __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
+ __RES; \
+ })
+#endif
+
+
+/**
+ \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 *ptr)
+{
+ uint32_t result;
+
+ __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) );
+ 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 *ptr)
+{
+ uint32_t result;
+
+ __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) );
+ 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 *ptr)
+{
+ uint32_t result;
+
+ __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) );
+ 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 *ptr)
+{
+ __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "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 *ptr)
+{
+ __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "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 *ptr)
+{
+ __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) );
+}
+
+#endif /* ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) */
+
+
+#if (__ARM_ARCH_8M__ == 1U)
+
+/**
+ \brief Load-Acquire (8 bit)
+ \details Executes a LDAB 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 __LDAB(volatile uint8_t *ptr)
+{
+ uint32_t result;
+
+ __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) );
+ return ((uint8_t) result);
+}
+
+
+/**
+ \brief Load-Acquire (16 bit)
+ \details Executes a LDAH 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 __LDAH(volatile uint16_t *ptr)
+{
+ uint32_t result;
+
+ __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) );
+ return ((uint16_t) result);
+}
+
+
+/**
+ \brief Load-Acquire (32 bit)
+ \details Executes a LDA 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 __LDA(volatile uint32_t *ptr)
+{
+ uint32_t result;
+
+ __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) );
+ return(result);
+}
+
+
+/**
+ \brief Store-Release (8 bit)
+ \details Executes a STLB instruction for 8 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __STLB(uint8_t value, volatile uint8_t *ptr)
+{
+ __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) );
+}
+
+
+/**
+ \brief Store-Release (16 bit)
+ \details Executes a STLH instruction for 16 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __STLH(uint16_t value, volatile uint16_t *ptr)
+{
+ __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) );
+}
+
+
+/**
+ \brief Store-Release (32 bit)
+ \details Executes a STL instruction for 32 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __STL(uint32_t value, volatile uint32_t *ptr)
+{
+ __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) );
+}
+
+
+/**
+ \brief Load-Acquire Exclusive (8 bit)
+ \details Executes a LDAB exclusive instruction for 8 bit value.
+ \param [in] ptr Pointer to data
+ \return value of type uint8_t at (*ptr)
+ */
+#define __LDAEXB (uint8_t)__builtin_arm_ldaex
+
+
+/**
+ \brief Load-Acquire Exclusive (16 bit)
+ \details Executes a LDAH exclusive instruction for 16 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint16_t at (*ptr)
+ */
+#define __LDAEXH (uint16_t)__builtin_arm_ldaex
+
+
+/**
+ \brief Load-Acquire Exclusive (32 bit)
+ \details Executes a LDA exclusive instruction for 32 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint32_t at (*ptr)
+ */
+#define __LDAEX (uint32_t)__builtin_arm_ldaex
+
+
+/**
+ \brief Store-Release Exclusive (8 bit)
+ \details Executes a STLB exclusive 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
+ */
+#define __STLEXB (uint32_t)__builtin_arm_stlex
+
+
+/**
+ \brief Store-Release Exclusive (16 bit)
+ \details Executes a STLH exclusive 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
+ */
+#define __STLEXH (uint32_t)__builtin_arm_stlex
+
+
+/**
+ \brief Store-Release Exclusive (32 bit)
+ \details Executes a STL exclusive 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
+ */
+#define __STLEX (uint32_t)__builtin_arm_stlex
+
+#endif /* (__ARM_ARCH_8M__ == 1U) */
+
+/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
+
+
+/* ################### Compiler specific Intrinsics ########################### */
+/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
+ Access to dedicated SIMD instructions
+ @{
+*/
+
+#if (__ARM_FEATURE_DSP == 1U) /* ToDo: ARMCC_V6: This should be ARCH >= ARMv7-M + SIMD */
+
+__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) \
+({ \
+ uint32_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 /* (__ARM_FEATURE_DSP == 1U) */
+/*@} end of group CMSIS_SIMD_intrinsics */
+
+
+#endif /* __CMSIS_ARMCC_V6_H */
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/CM0/Core/cmsis_gcc.h b/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/CM0/Core/cmsis_gcc.h
new file mode 100644
index 0000000..85e1235
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/CM0/Core/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));
+}
+
+
+/**
+ \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/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/CM0/Core/core_cm0.h b/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/CM0/Core/core_cm0.h
new file mode 100644
index 0000000..711dad5
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/CM0/Core/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/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/CM0/Core/core_cm0plus.h b/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/CM0/Core/core_cm0plus.h
new file mode 100644
index 0000000..b04aa39
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/CM0/Core/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/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/CM0/Core/core_cmFunc.h b/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/CM0/Core/core_cmFunc.h
new file mode 100644
index 0000000..652a48a
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/CM0/Core/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/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/CM0/Core/core_cmInstr.h b/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/CM0/Core/core_cmInstr.h
new file mode 100644
index 0000000..f474b0e
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/CM0/Core/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/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/CM0/Core/core_cmSimd.h b/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/CM0/Core/core_cmSimd.h
new file mode 100644
index 0000000..66bf5c2
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/CM0/Core/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/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/CM0/Core/core_sc000.h b/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/CM0/Core/core_sc000.h
new file mode 100644
index 0000000..514dbd8
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/CM0/Core/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/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/HK32F030M/Include/hk32f030m.h b/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/HK32F030M/Include/hk32f030m.h
new file mode 100644
index 0000000..f2f1eff
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/HK32F030M/Include/hk32f030m.h
@@ -0,0 +1,4666 @@
+/*
+ * HKMicroChip Limited (HKMicroChip) is supplying this software for use with Cortex-M0!
+ *
+ * @file hk32f030m.h
+ * @brief CMSIS HeaderFile
+ * @version 1.0
+ * @date 01. March 2020
+ * @Author Rakan.Z
+ */
+
+
+
+/** @addtogroup HKMicroChip Ltd.
+ * @{
+ */
+
+
+/** @addtogroup HK32F030M
+ * @{
+ */
+
+
+#ifndef HK32F030M_H
+#define HK32F030M_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (HK32F030MJ4M6) && !defined (HK32F030MD4P6) && !defined (HK32F030MF4P6) && !defined (HK32F030MF4U6)
+ #error "Please define the target HK32F030M device used in your application"
+#endif
+
+/** @addtogroup Configuration_of_CMSIS
+ * @{
+ */
+
+
+
+/* =========================================================================================================================== */
+/* ================ Interrupt Number Definition ================ */
+/* =========================================================================================================================== */
+typedef enum
+{
+/****** Cortex-M0 Processor Exceptions Numbers **************************************************************/
+ NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */
+ HardFault_IRQn = -13, /*!< 3 Cortex-M0 Hard Fault Interrupt */
+ SVC_IRQn = -5, /*!< 11 Cortex-M0 SV Call Interrupt */
+ PendSV_IRQn = -2, /*!< 14 Cortex-M0 Pend SV Interrupt */
+ SysTick_IRQn = -1, /*!< 15 Cortex-M0 System Tick Interrupt */
+
+/****** HK32F030M specific Interrupt Numbers ******************************************************************/
+ WWDG_IRQn = 0, /*!< Window WatchDog Interrupt */
+ EXTI11_IRQn = 2, /* EXTI Line 11 interrupt(AWU_WKP) */
+ FLASH_IRQn = 3, /*!< FLASH global Interrupt */
+ RCC_IRQn = 4, /*!< RCC global Interrupt */
+ EXTI0_IRQn = 5, /*!< EXTI Line 0 Interrupt */
+ EXTI1_IRQn = 6, /*!< EXTI Line 1 Interrupt */
+ EXTI2_IRQn = 7, /*!< EXTI Line 2 Interrupt */
+ EXTI3_IRQn = 8, /*!*!< EXTI Line 3 Interrupt */
+ EXTI4_IRQn = 9, /*!*!< EXTI Line 4 Interrupt */
+ EXTI5_IRQn = 10, /*!*!< EXTI Line 5 Interrupt */
+ TIM1_BRK_IRQn = 11, /*!< TIM1 break interrupt */
+ ADC1_IRQn = 12, /*!< ADC1 Interrupt(combined with EXTI line 8) */
+ TIM1_UP_TRG_COM_IRQn = 13, /*!< TIM1 Update, Trigger and Commutation Interrupt */
+ TIM1_CC_IRQn = 14, /*!< TIM1 Capture Compare Interrupt */
+ TIM2_IRQn = 15, /*!< TIM2 global interrupt */
+ TIM6_IRQn = 17, /*!< TIM6 global Interrupt */
+ EXTI6_IRQn = 21, /*!*!< EXTI Line 6 Interrupt */
+ EXTI7_IRQn = 22, /*!*!< EXTI Line 7 Interrupt */
+ I2C1_IRQn = 23, /*!< I2C1 Event Interrupt */
+ SPI1_IRQn = 25, /*!< SPI1 global Interrupt */
+ USART1_IRQn = 27, /*!< USART1 global Interrupt */
+} IRQn_Type;
+
+
+/* =========================================================================================================================== */
+/* ================ Processor and Core Peripheral Section ================ */
+/* =========================================================================================================================== */
+
+/* =========================== Configuration of the ARM Cortex-M0 Processor and Core Peripherals =========================== */
+#define __CM0_REV 0x0000U /*!< CM0 Core Revision */
+#define __NVIC_PRIO_BITS 3 /*!< Number of Bits used for Priority Levels */
+#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */
+#define __MPU_PRESENT 0 /*!< MPU present */
+#define __FPU_PRESENT 0 /*!< FPU present */
+
+
+/** @} */ /* End of group Configuration_of_CMSIS */
+
+#include "core_cm0.h" /*!< ARM Cortex-M0 processor and core peripherals */
+#include "system_hk32f030m.h" /*!< hk32f030m System */
+
+#ifndef __IM /*!< Fallback for older CMSIS versions */
+ #define __IM __I
+#endif
+#ifndef __OM /*!< Fallback for older CMSIS versions */
+ #define __OM __O
+#endif
+#ifndef __IOM /*!< Fallback for older CMSIS versions */
+ #define __IOM __IO
+#endif
+
+
+/* ======================================== Start of section using anonymous unions ======================================== */
+#if defined (__CC_ARM)
+ #pragma push
+ #pragma anon_unions
+#elif defined (__ICCARM__)
+ #pragma language=extended
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #pragma clang diagnostic push
+ #pragma clang diagnostic ignored "-Wc11-extensions"
+ #pragma clang diagnostic ignored "-Wreserved-id-macro"
+ #pragma clang diagnostic ignored "-Wgnu-anonymous-struct"
+ #pragma clang diagnostic ignored "-Wnested-anon-types"
+#elif defined (__GNUC__)
+ /* anonymous unions are enabled by default */
+#elif defined (__TMS470__)
+ /* anonymous unions are enabled by default */
+#elif defined (__TASKING__)
+ #pragma warning 586
+#elif defined (__CSMC__)
+ /* anonymous unions are enabled by default */
+#else
+ #warning Not supported compiler type
+#endif
+
+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;
+
+/* =========================================================================================================================== */
+/* ================ Device Specific Peripheral Section ================ */
+/* =========================================================================================================================== */
+
+
+/** @addtogroup Peripheral_registers_structures
+ * @{
+ */
+
+/**
+ * @brief Analog to Digital Converter
+ */
+typedef struct
+{
+ __IO uint32_t ISR; /*!< ADC interrupt and status register, Address offset: 0x00 */
+ __IO uint32_t IER; /*!< ADC interrupt enable register, Address offset: 0x04 */
+ __IO uint32_t CR; /*!< ADC control register, Address offset: 0x08 */
+ __IO uint32_t CFGR1; /*!< ADC configuration register 1, Address offset: 0x0C */
+ __IO uint32_t CFGR2; /*!< ADC configuration register 2, Address offset: 0x10 */
+ __IO uint32_t SMPR; /*!< ADC sampling time register, Address offset: 0x14 */
+ uint32_t RESERVED1; /*!< Reserved, 0x18 */
+ uint32_t RESERVED2; /*!< Reserved, 0x1C */
+ __IO uint32_t TR; /*!< ADC analog watchdog 1 threshold register, Address offset: 0x20 */
+ uint32_t RESERVED3; /*!< Reserved, 0x24 */
+ __IO uint32_t CHSELR; /*!< ADC group regular sequencer register, Address offset: 0x28 */
+ uint32_t RESERVED4[5]; /*!< Reserved, 0x2C */
+ __IO uint32_t DR; /*!< ADC group regular data register, Address offset: 0x40 */
+ uint32_t RESERVED5[177]; /*!< Reserved, Address offset:0x44 - 0x304*/
+ __IO uint32_t CCR; /*!< ADC common configuration register Address offset: 0x308 */
+ uint32_t RESERVED6[57];/*!< Reserved, Address offset: 0x30C */
+ __IO uint32_t CR2; /*!< ADC control register Address offset: 0x3f0 */
+} ADC_TypeDef;
+
+/**
+ * @brief CRC calculation unit
+ */
+
+typedef struct
+{
+ __IO uint32_t DR; /*!< CRC Data register, Address offset: 0x00 */
+ __IO uint8_t IDR; /*!< CRC Independent data register, Address offset: 0x04 */
+ uint8_t RESERVED0; /*!< Reserved, 0x05 */
+ uint16_t RESERVED1; /*!< Reserved, 0x06 */
+ __IO uint32_t CR; /*!< CRC Control register, Address offset: 0x08 */
+ uint32_t RESERVED2; /*!< Reserved, 0x0C */
+ __IO uint32_t INIT; /*!< Initial CRC value register, Address offset: 0x10 */
+ __IO uint32_t RESERVED3; /*!< Reserved, 0x14 */
+} CRC_TypeDef;
+
+/**
+ * @brief Debug MCU
+ */
+
+typedef struct
+{
+ __IO uint32_t IDCODE; /*!< MCU device ID code, Address offset: 0x00 */
+ __IO uint32_t CR; /*!< Debug MCU configuration register, Address offset: 0x04 */
+ __IO uint32_t APB1FZ; /*!< Debug MCU APB1 freeze register, Address offset: 0x08 */
+}DBGMCU_TypeDef;
+
+
+/**
+ * @brief External Interrupt/Event Controller
+ */
+
+typedef struct
+{
+ __IO uint32_t IMR; /*!= 6010050)
+ #pragma clang diagnostic pop
+#elif defined (__GNUC__)
+ /* anonymous unions are enabled by default */
+#elif defined (__TMS470__)
+ /* anonymous unions are enabled by default */
+#elif defined (__TASKING__)
+ #pragma warning restore
+#elif defined (__CSMC__)
+ /* anonymous unions are enabled by default */
+#endif
+
+/** @addtogroup Exported_constants
+ * @{
+ */
+
+ /** @addtogroup Peripheral_Registers_Bits_Definition
+ * @{
+ */
+
+/******************************************************************************/
+/* Peripheral Registers Bits Definition */
+/******************************************************************************/
+
+/******************************************************************************/
+/* */
+/* Analog to Digital Converter (ADC) */
+/* */
+/******************************************************************************/
+
+/* Note: No specific macro feature on this device */
+
+/******************** Bits definition for ADC_ISR register ******************/
+#define ADC_ISR_ADRDY_Pos (0U)
+#define ADC_ISR_ADRDY_Msk (0x1U << ADC_ISR_ADRDY_Pos) /*!< 0x00000001 */
+#define ADC_ISR_ADRDY ADC_ISR_ADRDY_Msk /*!< ADC ready flag */
+#define ADC_ISR_EOSMP_Pos (1U)
+#define ADC_ISR_EOSMP_Msk (0x1U << ADC_ISR_EOSMP_Pos) /*!< 0x00000002 */
+#define ADC_ISR_EOSMP ADC_ISR_EOSMP_Msk /*!< ADC group regular end of sampling flag */
+#define ADC_ISR_EOC_Pos (2U)
+#define ADC_ISR_EOC_Msk (0x1U << ADC_ISR_EOC_Pos) /*!< 0x00000004 */
+#define ADC_ISR_EOC ADC_ISR_EOC_Msk /*!< ADC group regular end of unitary conversion flag */
+#define ADC_ISR_EOS_Pos (3U)
+#define ADC_ISR_EOS_Msk (0x1U << ADC_ISR_EOS_Pos) /*!< 0x00000008 */
+#define ADC_ISR_EOS ADC_ISR_EOS_Msk /*!< ADC group regular end of sequence conversions flag */
+#define ADC_ISR_OVR_Pos (4U)
+#define ADC_ISR_OVR_Msk (0x1U << ADC_ISR_OVR_Pos) /*!< 0x00000010 */
+#define ADC_ISR_OVR ADC_ISR_OVR_Msk /*!< ADC group regular overrun flag */
+#define ADC_ISR_AWD1_Pos (7U)
+#define ADC_ISR_AWD1_Msk (0x1U << ADC_ISR_AWD1_Pos) /*!< 0x00000080 */
+#define ADC_ISR_AWD1 ADC_ISR_AWD1_Msk /*!< ADC analog watchdog 1 flag */
+
+/* Legacy defines */
+#define ADC_ISR_AWD (ADC_ISR_AWD1)
+#define ADC_ISR_EOSEQ (ADC_ISR_EOS)
+
+/******************** Bits definition for ADC_IER register ******************/
+#define ADC_IER_ADRDYIE_Pos (0U)
+#define ADC_IER_ADRDYIE_Msk (0x1U << ADC_IER_ADRDYIE_Pos) /*!< 0x00000001 */
+#define ADC_IER_ADRDYIE ADC_IER_ADRDYIE_Msk /*!< ADC ready interrupt */
+#define ADC_IER_EOSMPIE_Pos (1U)
+#define ADC_IER_EOSMPIE_Msk (0x1U << ADC_IER_EOSMPIE_Pos) /*!< 0x00000002 */
+#define ADC_IER_EOSMPIE ADC_IER_EOSMPIE_Msk /*!< ADC group regular end of sampling interrupt */
+#define ADC_IER_EOCIE_Pos (2U)
+#define ADC_IER_EOCIE_Msk (0x1U << ADC_IER_EOCIE_Pos) /*!< 0x00000004 */
+#define ADC_IER_EOCIE ADC_IER_EOCIE_Msk /*!< ADC group regular end of unitary conversion interrupt */
+#define ADC_IER_EOSIE_Pos (3U)
+#define ADC_IER_EOSIE_Msk (0x1U << ADC_IER_EOSIE_Pos) /*!< 0x00000008 */
+#define ADC_IER_EOSIE ADC_IER_EOSIE_Msk /*!< ADC group regular end of sequence conversions interrupt */
+#define ADC_IER_OVRIE_Pos (4U)
+#define ADC_IER_OVRIE_Msk (0x1U << ADC_IER_OVRIE_Pos) /*!< 0x00000010 */
+#define ADC_IER_OVRIE ADC_IER_OVRIE_Msk /*!< ADC group regular overrun interrupt */
+#define ADC_IER_AWD1IE_Pos (7U)
+#define ADC_IER_AWD1IE_Msk (0x1U << ADC_IER_AWD1IE_Pos) /*!< 0x00000080 */
+#define ADC_IER_AWD1IE ADC_IER_AWD1IE_Msk /*!< ADC analog watchdog 1 interrupt */
+
+/* Legacy defines */
+#define ADC_IER_AWDIE (ADC_IER_AWD1IE)
+#define ADC_IER_EOSEQIE (ADC_IER_EOSIE)
+
+/******************** Bits definition for ADC_CR register *******************/
+#define ADC_CR_ADEN_Pos (0U)
+#define ADC_CR_ADEN_Msk (0x1U << ADC_CR_ADEN_Pos) /*!< 0x00000001 */
+#define ADC_CR_ADEN ADC_CR_ADEN_Msk /*!< ADC enable */
+#define ADC_CR_ADDIS_Pos (1U)
+#define ADC_CR_ADDIS_Msk (0x1U << ADC_CR_ADDIS_Pos) /*!< 0x00000002 */
+#define ADC_CR_ADDIS ADC_CR_ADDIS_Msk /*!< ADC disable */
+#define ADC_CR_ADSTART_Pos (2U)
+#define ADC_CR_ADSTART_Msk (0x1U << ADC_CR_ADSTART_Pos) /*!< 0x00000004 */
+#define ADC_CR_ADSTART ADC_CR_ADSTART_Msk /*!< ADC group regular conversion start */
+#define ADC_CR_ADSTP_Pos (4U)
+#define ADC_CR_ADSTP_Msk (0x1U << ADC_CR_ADSTP_Pos) /*!< 0x00000010 */
+#define ADC_CR_ADSTP ADC_CR_ADSTP_Msk /*!< ADC group regular conversion stop */
+#define ADC_CR_ADCAL_Pos (31U)
+#define ADC_CR_ADCAL_Msk (0x1U << ADC_CR_ADCAL_Pos) /*!< 0x80000000 */
+#define ADC_CR_ADCAL ADC_CR_ADCAL_Msk /*!< ADC calibration */
+
+/******************* Bits definition for ADC_CFGR1 register *****************/
+#define ADC_CFGR1_SCANDIR_Pos (2U)
+#define ADC_CFGR1_SCANDIR_Msk (0x1U << ADC_CFGR1_SCANDIR_Pos) /*!< 0x00000004 */
+#define ADC_CFGR1_SCANDIR ADC_CFGR1_SCANDIR_Msk /*!< ADC group regular sequencer scan direction */
+
+#define ADC_CFGR1_ALIGN_Pos (5U)
+#define ADC_CFGR1_ALIGN_Msk (0x1U << ADC_CFGR1_ALIGN_Pos) /*!< 0x00000020 */
+#define ADC_CFGR1_ALIGN ADC_CFGR1_ALIGN_Msk /*!< ADC data alignement */
+
+#define ADC_CFGR1_EXTSEL_Pos (6U)
+#define ADC_CFGR1_EXTSEL_Msk (0x7U << ADC_CFGR1_EXTSEL_Pos) /*!< 0x000001C0 */
+#define ADC_CFGR1_EXTSEL ADC_CFGR1_EXTSEL_Msk /*!< ADC group regular external trigger source */
+#define ADC_CFGR1_EXTSEL_0 (0x1U << ADC_CFGR1_EXTSEL_Pos) /*!< 0x00000040 */
+#define ADC_CFGR1_EXTSEL_1 (0x2U << ADC_CFGR1_EXTSEL_Pos) /*!< 0x00000080 */
+#define ADC_CFGR1_EXTSEL_2 (0x4U << ADC_CFGR1_EXTSEL_Pos) /*!< 0x00000100 */
+//#define ADC_CFGR1_EXTSEL_3 (0x4U << ADC_CFGR1_EXTSEL_Pos) /*!< 0x00000100 */
+
+#define ADC_CFGR1_EXTEN_Pos (10U)
+#define ADC_CFGR1_EXTEN_Msk (0x3U << ADC_CFGR1_EXTEN_Pos) /*!< 0x00000C00 */
+#define ADC_CFGR1_EXTEN ADC_CFGR1_EXTEN_Msk /*!< ADC group regular external trigger polarity */
+#define ADC_CFGR1_EXTEN_0 (0x1U << ADC_CFGR1_EXTEN_Pos) /*!< 0x00000400 */
+#define ADC_CFGR1_EXTEN_1 (0x2U << ADC_CFGR1_EXTEN_Pos) /*!< 0x00000800 */
+
+#define ADC_CFGR1_OVRMOD_Pos (12U)
+#define ADC_CFGR1_OVRMOD_Msk (0x1U << ADC_CFGR1_OVRMOD_Pos) /*!< 0x00001000 */
+#define ADC_CFGR1_OVRMOD ADC_CFGR1_OVRMOD_Msk /*!< ADC group regular overrun configuration */
+#define ADC_CFGR1_CONT_Pos (13U)
+#define ADC_CFGR1_CONT_Msk (0x1U << ADC_CFGR1_CONT_Pos) /*!< 0x00002000 */
+#define ADC_CFGR1_CONT ADC_CFGR1_CONT_Msk /*!< ADC group regular continuous conversion mode */
+#define ADC_CFGR1_WAIT_Pos (14U)
+#define ADC_CFGR1_WAIT_Msk (0x1U << ADC_CFGR1_WAIT_Pos) /*!< 0x00004000 */
+#define ADC_CFGR1_WAIT ADC_CFGR1_WAIT_Msk /*!< ADC low power auto wait */
+#define ADC_CFGR1_AUTOFF_Pos (15U)
+#define ADC_CFGR1_AUTOFF_Msk (0x1U << ADC_CFGR1_AUTOFF_Pos) /*!< 0x00008000 */
+#define ADC_CFGR1_AUTOFF ADC_CFGR1_AUTOFF_Msk /*!< ADC low power auto power off */
+#define ADC_CFGR1_DISCEN_Pos (16U)
+#define ADC_CFGR1_DISCEN_Msk (0x1U << ADC_CFGR1_DISCEN_Pos) /*!< 0x00010000 */
+#define ADC_CFGR1_DISCEN ADC_CFGR1_DISCEN_Msk /*!< ADC group regular sequencer discontinuous mode */
+
+#define ADC_CFGR1_AWD1SGL_Pos (22U)
+#define ADC_CFGR1_AWD1SGL_Msk (0x1U << ADC_CFGR1_AWD1SGL_Pos) /*!< 0x00400000 */
+#define ADC_CFGR1_AWD1SGL ADC_CFGR1_AWD1SGL_Msk /*!< ADC analog watchdog 1 monitoring a single channel or all channels */
+#define ADC_CFGR1_AWD1EN_Pos (23U)
+#define ADC_CFGR1_AWD1EN_Msk (0x1U << ADC_CFGR1_AWD1EN_Pos) /*!< 0x00800000 */
+#define ADC_CFGR1_AWD1EN ADC_CFGR1_AWD1EN_Msk /*!< ADC analog watchdog 1 enable on scope ADC group regular */
+
+#define ADC_CFGR1_AWD1CH_Pos (26U)
+#define ADC_CFGR1_AWD1CH_Msk (0x7U << ADC_CFGR1_AWD1CH_Pos) /*!< 0x7C000000 */
+#define ADC_CFGR1_AWD1CH ADC_CFGR1_AWD1CH_Msk /*!< ADC analog watchdog 1 monitored channel selection */
+#define ADC_CFGR1_AWD1CH_0 (0x01U << ADC_CFGR1_AWD1CH_Pos) /*!< 0x04000000 */
+#define ADC_CFGR1_AWD1CH_1 (0x02U << ADC_CFGR1_AWD1CH_Pos) /*!< 0x08000000 */
+#define ADC_CFGR1_AWD1CH_2 (0x04U << ADC_CFGR1_AWD1CH_Pos) /*!< 0x10000000 */
+#define ADC_CFGR1_AWD1CH_3 (0x08U << ADC_CFGR1_AWD1CH_Pos) /*!< 0x20000000 */
+#define ADC_CFGR1_AWD1CH_4 (0x10U << ADC_CFGR1_AWD1CH_Pos) /*!< 0x40000000 */
+
+/* Legacy defines */
+#define ADC_CFGR1_AUTDLY (ADC_CFGR1_WAIT)
+#define ADC_CFGR1_AWDSGL (ADC_CFGR1_AWD1SGL)
+#define ADC_CFGR1_AWDEN (ADC_CFGR1_AWD1EN)
+#define ADC_CFGR1_AWDCH (ADC_CFGR1_AWD1CH)
+#define ADC_CFGR1_AWDCH_0 (ADC_CFGR1_AWD1CH_0)
+#define ADC_CFGR1_AWDCH_1 (ADC_CFGR1_AWD1CH_1)
+#define ADC_CFGR1_AWDCH_2 (ADC_CFGR1_AWD1CH_2)
+#define ADC_CFGR1_AWDCH_3 (ADC_CFGR1_AWD1CH_3)
+#define ADC_CFGR1_AWDCH_4 (ADC_CFGR1_AWD1CH_4)
+
+/******************* Bits definition for ADC_CFGR2 register *****************/
+#define ADC_CFGR2_CKMODE_Pos (30U)
+#define ADC_CFGR2_CKMODE_Msk (0x3U << ADC_CFGR2_CKMODE_Pos) /*!< 0xC0000000 */
+#define ADC_CFGR2_CKMODE ADC_CFGR2_CKMODE_Msk /*!< ADC clock source and prescaler (prescaler only for clock source synchronous) */
+#define ADC_CFGR2_CKMODE_1 (0x2U << ADC_CFGR2_CKMODE_Pos) /*!< 0x80000000 */
+#define ADC_CFGR2_CKMODE_0 (0x1U << ADC_CFGR2_CKMODE_Pos) /*!< 0x40000000 */
+
+/* Legacy defines */
+#define ADC_CFGR2_JITOFFDIV4 (ADC_CFGR2_CKMODE_1) /*!< ADC clocked by PCLK div4 */
+#define ADC_CFGR2_JITOFFDIV2 (ADC_CFGR2_CKMODE_0) /*!< ADC clocked by PCLK div2 */
+
+/****************** Bit definition for ADC_SMPR register ********************/
+#define ADC_SMPR_SMP_Pos (0U)
+#define ADC_SMPR_SMP_Msk (0x7U << ADC_SMPR_SMP_Pos) /*!< 0x00000007 */
+#define ADC_SMPR_SMP ADC_SMPR_SMP_Msk /*!< ADC group of channels sampling time 2 */
+#define ADC_SMPR_SMP_0 (0x1U << ADC_SMPR_SMP_Pos) /*!< 0x00000001 */
+#define ADC_SMPR_SMP_1 (0x2U << ADC_SMPR_SMP_Pos) /*!< 0x00000002 */
+#define ADC_SMPR_SMP_2 (0x4U << ADC_SMPR_SMP_Pos) /*!< 0x00000004 */
+
+/* Legacy defines */
+#define ADC_SMPR1_SMPR (ADC_SMPR_SMP) /*!< SMP[2:0] bits (Sampling time selection) */
+#define ADC_SMPR1_SMPR_0 (ADC_SMPR_SMP_0) /*!< bit 0 */
+#define ADC_SMPR1_SMPR_1 (ADC_SMPR_SMP_1) /*!< bit 1 */
+#define ADC_SMPR1_SMPR_2 (ADC_SMPR_SMP_2) /*!< bit 2 */
+
+/******************* Bit definition for ADC_TR register ********************/
+#define ADC_TR1_LT1_Pos (0U)
+#define ADC_TR1_LT1_Msk (0xFFFU << ADC_TR1_LT1_Pos) /*!< 0x00000FFF */
+#define ADC_TR1_LT1 ADC_TR1_LT1_Msk /*!< ADC analog watchdog 1 threshold low */
+#define ADC_TR1_LT1_0 (0x001U << ADC_TR1_LT1_Pos) /*!< 0x00000001 */
+#define ADC_TR1_LT1_1 (0x002U << ADC_TR1_LT1_Pos) /*!< 0x00000002 */
+#define ADC_TR1_LT1_2 (0x004U << ADC_TR1_LT1_Pos) /*!< 0x00000004 */
+#define ADC_TR1_LT1_3 (0x008U << ADC_TR1_LT1_Pos) /*!< 0x00000008 */
+#define ADC_TR1_LT1_4 (0x010U << ADC_TR1_LT1_Pos) /*!< 0x00000010 */
+#define ADC_TR1_LT1_5 (0x020U << ADC_TR1_LT1_Pos) /*!< 0x00000020 */
+#define ADC_TR1_LT1_6 (0x040U << ADC_TR1_LT1_Pos) /*!< 0x00000040 */
+#define ADC_TR1_LT1_7 (0x080U << ADC_TR1_LT1_Pos) /*!< 0x00000080 */
+#define ADC_TR1_LT1_8 (0x100U << ADC_TR1_LT1_Pos) /*!< 0x00000100 */
+#define ADC_TR1_LT1_9 (0x200U << ADC_TR1_LT1_Pos) /*!< 0x00000200 */
+#define ADC_TR1_LT1_10 (0x400U << ADC_TR1_LT1_Pos) /*!< 0x00000400 */
+#define ADC_TR1_LT1_11 (0x800U << ADC_TR1_LT1_Pos) /*!< 0x00000800 */
+
+#define ADC_TR1_HT1_Pos (16U)
+#define ADC_TR1_HT1_Msk (0xFFFU << ADC_TR1_HT1_Pos) /*!< 0x0FFF0000 */
+#define ADC_TR1_HT1 ADC_TR1_HT1_Msk /*!< ADC Analog watchdog 1 threshold high */
+#define ADC_TR1_HT1_0 (0x001U << ADC_TR1_HT1_Pos) /*!< 0x00010000 */
+#define ADC_TR1_HT1_1 (0x002U << ADC_TR1_HT1_Pos) /*!< 0x00020000 */
+#define ADC_TR1_HT1_2 (0x004U << ADC_TR1_HT1_Pos) /*!< 0x00040000 */
+#define ADC_TR1_HT1_3 (0x008U << ADC_TR1_HT1_Pos) /*!< 0x00080000 */
+#define ADC_TR1_HT1_4 (0x010U << ADC_TR1_HT1_Pos) /*!< 0x00100000 */
+#define ADC_TR1_HT1_5 (0x020U << ADC_TR1_HT1_Pos) /*!< 0x00200000 */
+#define ADC_TR1_HT1_6 (0x040U << ADC_TR1_HT1_Pos) /*!< 0x00400000 */
+#define ADC_TR1_HT1_7 (0x080U << ADC_TR1_HT1_Pos) /*!< 0x00800000 */
+#define ADC_TR1_HT1_8 (0x100U << ADC_TR1_HT1_Pos) /*!< 0x01000000 */
+#define ADC_TR1_HT1_9 (0x200U << ADC_TR1_HT1_Pos) /*!< 0x02000000 */
+#define ADC_TR1_HT1_10 (0x400U << ADC_TR1_HT1_Pos) /*!< 0x04000000 */
+#define ADC_TR1_HT1_11 (0x800U << ADC_TR1_HT1_Pos) /*!< 0x08000000 */
+
+/* Legacy defines */
+#define ADC_TR_HT (ADC_TR1_HT1)
+#define ADC_TR_LT (ADC_TR1_LT1)
+#define ADC_HTR_HT (ADC_TR1_HT1)
+#define ADC_LTR_LT (ADC_TR1_LT1)
+
+/****************** Bit definition for ADC_CHSELR register ******************/
+#define ADC_CHSELR_CHSEL_Pos (0U)
+#define ADC_CHSELR_CHSEL_Msk (0x7FFFFU << ADC_CHSELR_CHSEL_Pos) /*!< 0x0007FFFF */
+#define ADC_CHSELR_CHSEL ADC_CHSELR_CHSEL_Msk /*!< ADC group regular sequencer channels, available when ADC_CFGR1_CHSELRMOD is reset */
+#define ADC_CHSELR_CHSEL18_Pos (18U)
+#define ADC_CHSELR_CHSEL18_Msk (0x1U << ADC_CHSELR_CHSEL18_Pos) /*!< 0x00040000 */
+#define ADC_CHSELR_CHSEL18 ADC_CHSELR_CHSEL18_Msk /*!< ADC group regular sequencer channel 18, available when ADC_CFGR1_CHSELRMOD is reset */
+#define ADC_CHSELR_CHSEL17_Pos (17U)
+#define ADC_CHSELR_CHSEL17_Msk (0x1U << ADC_CHSELR_CHSEL17_Pos) /*!< 0x00020000 */
+#define ADC_CHSELR_CHSEL17 ADC_CHSELR_CHSEL17_Msk /*!< ADC group regular sequencer channel 17, available when ADC_CFGR1_CHSELRMOD is reset */
+#define ADC_CHSELR_CHSEL16_Pos (16U)
+#define ADC_CHSELR_CHSEL16_Msk (0x1U << ADC_CHSELR_CHSEL16_Pos) /*!< 0x00010000 */
+#define ADC_CHSELR_CHSEL16 ADC_CHSELR_CHSEL16_Msk /*!< ADC group regular sequencer channel 16, available when ADC_CFGR1_CHSELRMOD is reset */
+#define ADC_CHSELR_CHSEL15_Pos (15U)
+#define ADC_CHSELR_CHSEL15_Msk (0x1U << ADC_CHSELR_CHSEL15_Pos) /*!< 0x00008000 */
+#define ADC_CHSELR_CHSEL15 ADC_CHSELR_CHSEL15_Msk /*!< ADC group regular sequencer channel 15, available when ADC_CFGR1_CHSELRMOD is reset */
+#define ADC_CHSELR_CHSEL14_Pos (14U)
+#define ADC_CHSELR_CHSEL14_Msk (0x1U << ADC_CHSELR_CHSEL14_Pos) /*!< 0x00004000 */
+#define ADC_CHSELR_CHSEL14 ADC_CHSELR_CHSEL14_Msk /*!< ADC group regular sequencer channel 14, available when ADC_CFGR1_CHSELRMOD is reset */
+#define ADC_CHSELR_CHSEL13_Pos (13U)
+#define ADC_CHSELR_CHSEL13_Msk (0x1U << ADC_CHSELR_CHSEL13_Pos) /*!< 0x00002000 */
+#define ADC_CHSELR_CHSEL13 ADC_CHSELR_CHSEL13_Msk /*!< ADC group regular sequencer channel 13, available when ADC_CFGR1_CHSELRMOD is reset */
+#define ADC_CHSELR_CHSEL12_Pos (12U)
+#define ADC_CHSELR_CHSEL12_Msk (0x1U << ADC_CHSELR_CHSEL12_Pos) /*!< 0x00001000 */
+#define ADC_CHSELR_CHSEL12 ADC_CHSELR_CHSEL12_Msk /*!< ADC group regular sequencer channel 12, available when ADC_CFGR1_CHSELRMOD is reset */
+#define ADC_CHSELR_CHSEL11_Pos (11U)
+#define ADC_CHSELR_CHSEL11_Msk (0x1U << ADC_CHSELR_CHSEL11_Pos) /*!< 0x00000800 */
+#define ADC_CHSELR_CHSEL11 ADC_CHSELR_CHSEL11_Msk /*!< ADC group regular sequencer channel 11, available when ADC_CFGR1_CHSELRMOD is reset */
+#define ADC_CHSELR_CHSEL10_Pos (10U)
+#define ADC_CHSELR_CHSEL10_Msk (0x1U << ADC_CHSELR_CHSEL10_Pos) /*!< 0x00000400 */
+#define ADC_CHSELR_CHSEL10 ADC_CHSELR_CHSEL10_Msk /*!< ADC group regular sequencer channel 10, available when ADC_CFGR1_CHSELRMOD is reset */
+#define ADC_CHSELR_CHSEL9_Pos (9U)
+#define ADC_CHSELR_CHSEL9_Msk (0x1U << ADC_CHSELR_CHSEL9_Pos) /*!< 0x00000200 */
+#define ADC_CHSELR_CHSEL9 ADC_CHSELR_CHSEL9_Msk /*!< ADC group regular sequencer channel 9, available when ADC_CFGR1_CHSELRMOD is reset */
+#define ADC_CHSELR_CHSEL8_Pos (8U)
+#define ADC_CHSELR_CHSEL8_Msk (0x1U << ADC_CHSELR_CHSEL8_Pos) /*!< 0x00000100 */
+#define ADC_CHSELR_CHSEL8 ADC_CHSELR_CHSEL8_Msk /*!< ADC group regular sequencer channel 8, available when ADC_CFGR1_CHSELRMOD is reset */
+#define ADC_CHSELR_CHSEL7_Pos (7U)
+#define ADC_CHSELR_CHSEL7_Msk (0x1U << ADC_CHSELR_CHSEL7_Pos) /*!< 0x00000080 */
+#define ADC_CHSELR_CHSEL7 ADC_CHSELR_CHSEL7_Msk /*!< ADC group regular sequencer channel 7, available when ADC_CFGR1_CHSELRMOD is reset */
+#define ADC_CHSELR_CHSEL6_Pos (6U)
+#define ADC_CHSELR_CHSEL6_Msk (0x1U << ADC_CHSELR_CHSEL6_Pos) /*!< 0x00000040 */
+#define ADC_CHSELR_CHSEL6 ADC_CHSELR_CHSEL6_Msk /*!< ADC group regular sequencer channel 6, available when ADC_CFGR1_CHSELRMOD is reset */
+#define ADC_CHSELR_CHSEL5_Pos (5U)
+#define ADC_CHSELR_CHSEL5_Msk (0x1U << ADC_CHSELR_CHSEL5_Pos) /*!< 0x00000020 */
+#define ADC_CHSELR_CHSEL5 ADC_CHSELR_CHSEL5_Msk /*!< ADC group regular sequencer channel 5, available when ADC_CFGR1_CHSELRMOD is reset */
+#define ADC_CHSELR_CHSEL4_Pos (4U)
+#define ADC_CHSELR_CHSEL4_Msk (0x1U << ADC_CHSELR_CHSEL4_Pos) /*!< 0x00000010 */
+#define ADC_CHSELR_CHSEL4 ADC_CHSELR_CHSEL4_Msk /*!< ADC group regular sequencer channel 4, available when ADC_CFGR1_CHSELRMOD is reset */
+#define ADC_CHSELR_CHSEL3_Pos (3U)
+#define ADC_CHSELR_CHSEL3_Msk (0x1U << ADC_CHSELR_CHSEL3_Pos) /*!< 0x00000008 */
+#define ADC_CHSELR_CHSEL3 ADC_CHSELR_CHSEL3_Msk /*!< ADC group regular sequencer channel 3, available when ADC_CFGR1_CHSELRMOD is reset */
+#define ADC_CHSELR_CHSEL2_Pos (2U)
+#define ADC_CHSELR_CHSEL2_Msk (0x1U << ADC_CHSELR_CHSEL2_Pos) /*!< 0x00000004 */
+#define ADC_CHSELR_CHSEL2 ADC_CHSELR_CHSEL2_Msk /*!< ADC group regular sequencer channel 2, available when ADC_CFGR1_CHSELRMOD is reset */
+#define ADC_CHSELR_CHSEL1_Pos (1U)
+#define ADC_CHSELR_CHSEL1_Msk (0x1U << ADC_CHSELR_CHSEL1_Pos) /*!< 0x00000002 */
+#define ADC_CHSELR_CHSEL1 ADC_CHSELR_CHSEL1_Msk /*!< ADC group regular sequencer channel 1, available when ADC_CFGR1_CHSELRMOD is reset */
+#define ADC_CHSELR_CHSEL0_Pos (0U)
+#define ADC_CHSELR_CHSEL0_Msk (0x1U << ADC_CHSELR_CHSEL0_Pos) /*!< 0x00000001 */
+#define ADC_CHSELR_CHSEL0 ADC_CHSELR_CHSEL0_Msk /*!< ADC group regular sequencer channel 0, available when ADC_CFGR1_CHSELRMOD is reset */
+
+/******************** Bit definition for ADC_DR register ********************/
+#define ADC_DR_DATA_Pos (0U)
+#define ADC_DR_DATA_Msk (0xFFFFU << ADC_DR_DATA_Pos) /*!< 0x0000FFFF */
+#define ADC_DR_DATA ADC_DR_DATA_Msk /*!< ADC group regular conversion data */
+#define ADC_DR_DATA_0 (0x0001U << ADC_DR_DATA_Pos) /*!< 0x00000001 */
+#define ADC_DR_DATA_1 (0x0002U << ADC_DR_DATA_Pos) /*!< 0x00000002 */
+#define ADC_DR_DATA_2 (0x0004U << ADC_DR_DATA_Pos) /*!< 0x00000004 */
+#define ADC_DR_DATA_3 (0x0008U << ADC_DR_DATA_Pos) /*!< 0x00000008 */
+#define ADC_DR_DATA_4 (0x0010U << ADC_DR_DATA_Pos) /*!< 0x00000010 */
+#define ADC_DR_DATA_5 (0x0020U << ADC_DR_DATA_Pos) /*!< 0x00000020 */
+#define ADC_DR_DATA_6 (0x0040U << ADC_DR_DATA_Pos) /*!< 0x00000040 */
+#define ADC_DR_DATA_7 (0x0080U << ADC_DR_DATA_Pos) /*!< 0x00000080 */
+#define ADC_DR_DATA_8 (0x0100U << ADC_DR_DATA_Pos) /*!< 0x00000100 */
+#define ADC_DR_DATA_9 (0x0200U << ADC_DR_DATA_Pos) /*!< 0x00000200 */
+#define ADC_DR_DATA_10 (0x0400U << ADC_DR_DATA_Pos) /*!< 0x00000400 */
+#define ADC_DR_DATA_11 (0x0800U << ADC_DR_DATA_Pos) /*!< 0x00000800 */
+#define ADC_DR_DATA_12 (0x1000U << ADC_DR_DATA_Pos) /*!< 0x00001000 */
+#define ADC_DR_DATA_13 (0x2000U << ADC_DR_DATA_Pos) /*!< 0x00002000 */
+#define ADC_DR_DATA_14 (0x4000U << ADC_DR_DATA_Pos) /*!< 0x00004000 */
+#define ADC_DR_DATA_15 (0x8000U << ADC_DR_DATA_Pos) /*!< 0x00008000 */
+
+/************************* ADC Common registers *****************************/
+/******************* Bit definition for ADC_CCR register ********************/
+#define ADC_CCR_VREFEN_Pos (22U)
+#define ADC_CCR_VREFEN_Msk (0x1U << ADC_CCR_VREFEN_Pos) /*!< 0x00400000 */
+#define ADC_CCR_VREFEN ADC_CCR_VREFEN_Msk /*!< ADC internal path to VrefInt enable */
+
+/************************* ADC CR2 registers *****************************/
+/******************* Bit definition for ADC_CR2 register ********************/
+#define ADC_CR2_GCMP_Pos (0)
+#define ADC_CR2_GCMP (0x00000001ul)
+#define ADC_CR2_SDIF_Pos (1)
+#define ADC_CR2_SDIF (0x00000001ul << ADC_CR2_SDIF_Pos)
+#define ADC_CR2_WAKE_EN_Pos (31)
+#define ADC_CR2_WAKE_EN (0x00000001ul << ADC_CR2_WAKE_EN_Pos)
+
+/******************************************************************************/
+/* */
+/* CRC calculation unit (CRC) */
+/* */
+/******************************************************************************/
+/******************* Bit definition for CRC_DR register *********************/
+#define CRC_DR_DR_Pos (0U)
+#define CRC_DR_DR_Msk (0xFFFFFFFFU << CRC_DR_DR_Pos) /*!< 0xFFFFFFFF */
+#define CRC_DR_DR CRC_DR_DR_Msk /*!< Data register bits */
+
+/******************* Bit definition for CRC_IDR register ********************/
+#define CRC_IDR_IDR ((uint8_t)0xFFU) /*!< General-purpose 8-bit data register bits */
+
+/******************** Bit definition for CRC_CR register ********************/
+#define CRC_CR_RESET_Pos (0U)
+#define CRC_CR_RESET_Msk (0x1U << CRC_CR_RESET_Pos) /*!< 0x00000001 */
+#define CRC_CR_RESET CRC_CR_RESET_Msk /*!< RESET the CRC computation unit bit */
+#define CRC_CR_REV_IN_Pos (5U)
+#define CRC_CR_REV_IN_Msk (0x3U << CRC_CR_REV_IN_Pos) /*!< 0x00000060 */
+#define CRC_CR_REV_IN CRC_CR_REV_IN_Msk /*!< REV_IN Reverse Input Data bits */
+#define CRC_CR_REV_IN_0 (0x1U << CRC_CR_REV_IN_Pos) /*!< 0x00000020 */
+#define CRC_CR_REV_IN_1 (0x2U << CRC_CR_REV_IN_Pos) /*!< 0x00000040 */
+#define CRC_CR_REV_OUT_Pos (7U)
+#define CRC_CR_REV_OUT_Msk (0x1U << CRC_CR_REV_OUT_Pos) /*!< 0x00000080 */
+#define CRC_CR_REV_OUT CRC_CR_REV_OUT_Msk /*!< REV_OUT Reverse Output Data bits */
+
+/******************* Bit definition for CRC_INIT register *******************/
+#define CRC_INIT_INIT_Pos (0U)
+#define CRC_INIT_INIT_Msk (0xFFFFFFFFU << CRC_INIT_INIT_Pos) /*!< 0xFFFFFFFF */
+#define CRC_INIT_INIT CRC_INIT_INIT_Msk /*!< Initial CRC value bits */
+
+/******************************************************************************/
+/* */
+/* Debug MCU (DBGMCU) */
+/* */
+/******************************************************************************/
+
+/**************** Bit definition for DBGMCU_IDCODE register *****************/
+#define DBGMCU_IDCODE_DEV_ID_Pos (0U)
+#define DBGMCU_IDCODE_DEV_ID_Msk (0xFFFU << DBGMCU_IDCODE_DEV_ID_Pos) /*!< 0x00000FFF */
+#define DBGMCU_IDCODE_DEV_ID DBGMCU_IDCODE_DEV_ID_Msk /*!< Device Identifier */
+
+#define DBGMCU_IDCODE_REV_ID_Pos (16U)
+#define DBGMCU_IDCODE_REV_ID_Msk (0xFFFFU << DBGMCU_IDCODE_REV_ID_Pos) /*!< 0xFFFF0000 */
+#define DBGMCU_IDCODE_REV_ID DBGMCU_IDCODE_REV_ID_Msk /*!< REV_ID[15:0] bits (Revision Identifier) */
+#define DBGMCU_IDCODE_REV_ID_0 (0x0001U << DBGMCU_IDCODE_REV_ID_Pos) /*!< 0x00010000 */
+#define DBGMCU_IDCODE_REV_ID_1 (0x0002U << DBGMCU_IDCODE_REV_ID_Pos) /*!< 0x00020000 */
+#define DBGMCU_IDCODE_REV_ID_2 (0x0004U << DBGMCU_IDCODE_REV_ID_Pos) /*!< 0x00040000 */
+#define DBGMCU_IDCODE_REV_ID_3 (0x0008U << DBGMCU_IDCODE_REV_ID_Pos) /*!< 0x00080000 */
+#define DBGMCU_IDCODE_REV_ID_4 (0x0010U << DBGMCU_IDCODE_REV_ID_Pos) /*!< 0x00100000 */
+#define DBGMCU_IDCODE_REV_ID_5 (0x0020U << DBGMCU_IDCODE_REV_ID_Pos) /*!< 0x00200000 */
+#define DBGMCU_IDCODE_REV_ID_6 (0x0040U << DBGMCU_IDCODE_REV_ID_Pos) /*!< 0x00400000 */
+#define DBGMCU_IDCODE_REV_ID_7 (0x0080U << DBGMCU_IDCODE_REV_ID_Pos) /*!< 0x00800000 */
+#define DBGMCU_IDCODE_REV_ID_8 (0x0100U << DBGMCU_IDCODE_REV_ID_Pos) /*!< 0x01000000 */
+#define DBGMCU_IDCODE_REV_ID_9 (0x0200U << DBGMCU_IDCODE_REV_ID_Pos) /*!< 0x02000000 */
+#define DBGMCU_IDCODE_REV_ID_10 (0x0400U << DBGMCU_IDCODE_REV_ID_Pos) /*!< 0x04000000 */
+#define DBGMCU_IDCODE_REV_ID_11 (0x0800U << DBGMCU_IDCODE_REV_ID_Pos) /*!< 0x08000000 */
+#define DBGMCU_IDCODE_REV_ID_12 (0x1000U << DBGMCU_IDCODE_REV_ID_Pos) /*!< 0x10000000 */
+#define DBGMCU_IDCODE_REV_ID_13 (0x2000U << DBGMCU_IDCODE_REV_ID_Pos) /*!< 0x20000000 */
+#define DBGMCU_IDCODE_REV_ID_14 (0x4000U << DBGMCU_IDCODE_REV_ID_Pos) /*!< 0x40000000 */
+#define DBGMCU_IDCODE_REV_ID_15 (0x8000U << DBGMCU_IDCODE_REV_ID_Pos) /*!< 0x80000000 */
+
+/****************** Bit definition for DBGMCU_CR register *******************/
+#define DBGMCU_CR_DBG_STOP_Pos (1U)
+#define DBGMCU_CR_DBG_STOP_Msk (0x1U << DBGMCU_CR_DBG_STOP_Pos) /*!< 0x00000002 */
+#define DBGMCU_CR_DBG_STOP DBGMCU_CR_DBG_STOP_Msk /*!< Debug Stop Mode */
+
+/****************** Bit definition for DBGMCU_APB1_FZ register **************/
+
+#define DBGMCU_APB1_FZ_DBG_TIM1_STOP_Pos (0U)
+#define DBGMCU_APB1_FZ_DBG_TIM1_STOP_Msk (0x1U << DBGMCU_APB1_FZ_DBG_TIM1_STOP_Pos) /*!< 0x00000001 */
+#define DBGMCU_APB1_FZ_DBG_TIM1_STOP DBGMCU_APB1_FZ_DBG_TIM1_STOP_Msk /*!< TIM2 counter stopped when core is halted */
+
+#define DBGMCU_APB1_FZ_DBG_TIM2_STOP_Pos (1U)
+#define DBGMCU_APB1_FZ_DBG_TIM2_STOP_Msk (0x1U << DBGMCU_APB1_FZ_DBG_TIM2_STOP_Pos) /*!< 0x00000002 */
+#define DBGMCU_APB1_FZ_DBG_TIM2_STOP DBGMCU_APB1_FZ_DBG_TIM2_STOP_Msk /*!< TIM3 counter stopped when core is halted */
+#define DBGMCU_APB1_FZ_DBG_TIM6_STOP_Pos (4U)
+#define DBGMCU_APB1_FZ_DBG_TIM6_STOP_Msk (0x1U << DBGMCU_APB1_FZ_DBG_TIM6_STOP_Pos) /*!< 0x00000010 */
+#define DBGMCU_APB1_FZ_DBG_TIM6_STOP DBGMCU_APB1_FZ_DBG_TIM6_STOP_Msk /*!< TIM6 counter stopped when core is halted */
+
+#define DBGMCU_APB1_FZ_DBG_WWDG_STOP_Pos (11U)
+#define DBGMCU_APB1_FZ_DBG_WWDG_STOP_Msk (0x1U << DBGMCU_APB1_FZ_DBG_WWDG_STOP_Pos) /*!< 0x00000800 */
+#define DBGMCU_APB1_FZ_DBG_WWDG_STOP DBGMCU_APB1_FZ_DBG_WWDG_STOP_Msk /*!< Debug Window Watchdog stopped when Core is halted */
+#define DBGMCU_APB1_FZ_DBG_IWDG_STOP_Pos (12U)
+#define DBGMCU_APB1_FZ_DBG_IWDG_STOP_Msk (0x1U << DBGMCU_APB1_FZ_DBG_IWDG_STOP_Pos) /*!< 0x00001000 */
+#define DBGMCU_APB1_FZ_DBG_IWDG_STOP DBGMCU_APB1_FZ_DBG_IWDG_STOP_Msk /*!< Debug Independent Watchdog stopped when Core is halted */
+#define DBGMCU_APB1_FZ_DBG_I2C1_SMBUS_TIMEOUT_Pos (21U)
+#define DBGMCU_APB1_FZ_DBG_I2C1_SMBUS_TIMEOUT_Msk (0x1U << DBGMCU_APB1_FZ_DBG_I2C1_SMBUS_TIMEOUT_Pos) /*!< 0x00200000 */
+#define DBGMCU_APB1_FZ_DBG_I2C1_SMBUS_TIMEOUT DBGMCU_APB1_FZ_DBG_I2C1_SMBUS_TIMEOUT_Msk /*!< I2C1 SMBUS timeout mode stopped when Core is halted */
+
+
+
+/******************************************************************************/
+/* */
+/* Nested Vectored Interrupt Controller */
+/* */
+/******************************************************************************/
+
+/****************** Bit definition for NVIC_ISER register *******************/
+#define NVIC_ISER_SETENA ((uint32_t)0xFFFFFFFF) /*!< Interrupt set enable bits */
+#define NVIC_ISER_SETENA_0 ((uint32_t)0x00000001) /*!< bit 0 */
+#define NVIC_ISER_SETENA_1 ((uint32_t)0x00000002) /*!< bit 1 */
+#define NVIC_ISER_SETENA_2 ((uint32_t)0x00000004) /*!< bit 2 */
+#define NVIC_ISER_SETENA_3 ((uint32_t)0x00000008) /*!< bit 3 */
+#define NVIC_ISER_SETENA_4 ((uint32_t)0x00000010) /*!< bit 4 */
+#define NVIC_ISER_SETENA_5 ((uint32_t)0x00000020) /*!< bit 5 */
+#define NVIC_ISER_SETENA_6 ((uint32_t)0x00000040) /*!< bit 6 */
+#define NVIC_ISER_SETENA_7 ((uint32_t)0x00000080) /*!< bit 7 */
+#define NVIC_ISER_SETENA_8 ((uint32_t)0x00000100) /*!< bit 8 */
+#define NVIC_ISER_SETENA_9 ((uint32_t)0x00000200) /*!< bit 9 */
+#define NVIC_ISER_SETENA_10 ((uint32_t)0x00000400) /*!< bit 10 */
+#define NVIC_ISER_SETENA_11 ((uint32_t)0x00000800) /*!< bit 11 */
+#define NVIC_ISER_SETENA_12 ((uint32_t)0x00001000) /*!< bit 12 */
+#define NVIC_ISER_SETENA_13 ((uint32_t)0x00002000) /*!< bit 13 */
+#define NVIC_ISER_SETENA_14 ((uint32_t)0x00004000) /*!< bit 14 */
+#define NVIC_ISER_SETENA_15 ((uint32_t)0x00008000) /*!< bit 15 */
+#define NVIC_ISER_SETENA_16 ((uint32_t)0x00010000) /*!< bit 16 */
+#define NVIC_ISER_SETENA_17 ((uint32_t)0x00020000) /*!< bit 17 */
+#define NVIC_ISER_SETENA_18 ((uint32_t)0x00040000) /*!< bit 18 */
+#define NVIC_ISER_SETENA_19 ((uint32_t)0x00080000) /*!< bit 19 */
+#define NVIC_ISER_SETENA_20 ((uint32_t)0x00100000) /*!< bit 20 */
+#define NVIC_ISER_SETENA_21 ((uint32_t)0x00200000) /*!< bit 21 */
+#define NVIC_ISER_SETENA_22 ((uint32_t)0x00400000) /*!< bit 22 */
+#define NVIC_ISER_SETENA_23 ((uint32_t)0x00800000) /*!< bit 23 */
+#define NVIC_ISER_SETENA_24 ((uint32_t)0x01000000) /*!< bit 24 */
+#define NVIC_ISER_SETENA_25 ((uint32_t)0x02000000) /*!< bit 25 */
+#define NVIC_ISER_SETENA_26 ((uint32_t)0x04000000) /*!< bit 26 */
+#define NVIC_ISER_SETENA_27 ((uint32_t)0x08000000) /*!< bit 27 */
+#define NVIC_ISER_SETENA_28 ((uint32_t)0x10000000) /*!< bit 28 */
+#define NVIC_ISER_SETENA_29 ((uint32_t)0x20000000) /*!< bit 29 */
+#define NVIC_ISER_SETENA_30 ((uint32_t)0x40000000) /*!< bit 30 */
+#define NVIC_ISER_SETENA_31 ((uint32_t)0x80000000) /*!< bit 31 */
+
+/****************** Bit definition for NVIC_ICER register *******************/
+#define NVIC_ICER_CLRENA ((uint32_t)0xFFFFFFFF) /*!< Interrupt clear-enable bits */
+#define NVIC_ICER_CLRENA_0 ((uint32_t)0x00000001) /*!< bit 0 */
+#define NVIC_ICER_CLRENA_1 ((uint32_t)0x00000002) /*!< bit 1 */
+#define NVIC_ICER_CLRENA_2 ((uint32_t)0x00000004) /*!< bit 2 */
+#define NVIC_ICER_CLRENA_3 ((uint32_t)0x00000008) /*!< bit 3 */
+#define NVIC_ICER_CLRENA_4 ((uint32_t)0x00000010) /*!< bit 4 */
+#define NVIC_ICER_CLRENA_5 ((uint32_t)0x00000020) /*!< bit 5 */
+#define NVIC_ICER_CLRENA_6 ((uint32_t)0x00000040) /*!< bit 6 */
+#define NVIC_ICER_CLRENA_7 ((uint32_t)0x00000080) /*!< bit 7 */
+#define NVIC_ICER_CLRENA_8 ((uint32_t)0x00000100) /*!< bit 8 */
+#define NVIC_ICER_CLRENA_9 ((uint32_t)0x00000200) /*!< bit 9 */
+#define NVIC_ICER_CLRENA_10 ((uint32_t)0x00000400) /*!< bit 10 */
+#define NVIC_ICER_CLRENA_11 ((uint32_t)0x00000800) /*!< bit 11 */
+#define NVIC_ICER_CLRENA_12 ((uint32_t)0x00001000) /*!< bit 12 */
+#define NVIC_ICER_CLRENA_13 ((uint32_t)0x00002000) /*!< bit 13 */
+#define NVIC_ICER_CLRENA_14 ((uint32_t)0x00004000) /*!< bit 14 */
+#define NVIC_ICER_CLRENA_15 ((uint32_t)0x00008000) /*!< bit 15 */
+#define NVIC_ICER_CLRENA_16 ((uint32_t)0x00010000) /*!< bit 16 */
+#define NVIC_ICER_CLRENA_17 ((uint32_t)0x00020000) /*!< bit 17 */
+#define NVIC_ICER_CLRENA_18 ((uint32_t)0x00040000) /*!< bit 18 */
+#define NVIC_ICER_CLRENA_19 ((uint32_t)0x00080000) /*!< bit 19 */
+#define NVIC_ICER_CLRENA_20 ((uint32_t)0x00100000) /*!< bit 20 */
+#define NVIC_ICER_CLRENA_21 ((uint32_t)0x00200000) /*!< bit 21 */
+#define NVIC_ICER_CLRENA_22 ((uint32_t)0x00400000) /*!< bit 22 */
+#define NVIC_ICER_CLRENA_23 ((uint32_t)0x00800000) /*!< bit 23 */
+#define NVIC_ICER_CLRENA_24 ((uint32_t)0x01000000) /*!< bit 24 */
+#define NVIC_ICER_CLRENA_25 ((uint32_t)0x02000000) /*!< bit 25 */
+#define NVIC_ICER_CLRENA_26 ((uint32_t)0x04000000) /*!< bit 26 */
+#define NVIC_ICER_CLRENA_27 ((uint32_t)0x08000000) /*!< bit 27 */
+#define NVIC_ICER_CLRENA_28 ((uint32_t)0x10000000) /*!< bit 28 */
+#define NVIC_ICER_CLRENA_29 ((uint32_t)0x20000000) /*!< bit 29 */
+#define NVIC_ICER_CLRENA_30 ((uint32_t)0x40000000) /*!< bit 30 */
+#define NVIC_ICER_CLRENA_31 ((uint32_t)0x80000000) /*!< bit 31 */
+
+/****************** Bit definition for NVIC_ISPR register *******************/
+#define NVIC_ISPR_SETPEND ((uint32_t)0xFFFFFFFF) /*!< Interrupt set-pending bits */
+#define NVIC_ISPR_SETPEND_0 ((uint32_t)0x00000001) /*!< bit 0 */
+#define NVIC_ISPR_SETPEND_1 ((uint32_t)0x00000002) /*!< bit 1 */
+#define NVIC_ISPR_SETPEND_2 ((uint32_t)0x00000004) /*!< bit 2 */
+#define NVIC_ISPR_SETPEND_3 ((uint32_t)0x00000008) /*!< bit 3 */
+#define NVIC_ISPR_SETPEND_4 ((uint32_t)0x00000010) /*!< bit 4 */
+#define NVIC_ISPR_SETPEND_5 ((uint32_t)0x00000020) /*!< bit 5 */
+#define NVIC_ISPR_SETPEND_6 ((uint32_t)0x00000040) /*!< bit 6 */
+#define NVIC_ISPR_SETPEND_7 ((uint32_t)0x00000080) /*!< bit 7 */
+#define NVIC_ISPR_SETPEND_8 ((uint32_t)0x00000100) /*!< bit 8 */
+#define NVIC_ISPR_SETPEND_9 ((uint32_t)0x00000200) /*!< bit 9 */
+#define NVIC_ISPR_SETPEND_10 ((uint32_t)0x00000400) /*!< bit 10 */
+#define NVIC_ISPR_SETPEND_11 ((uint32_t)0x00000800) /*!< bit 11 */
+#define NVIC_ISPR_SETPEND_12 ((uint32_t)0x00001000) /*!< bit 12 */
+#define NVIC_ISPR_SETPEND_13 ((uint32_t)0x00002000) /*!< bit 13 */
+#define NVIC_ISPR_SETPEND_14 ((uint32_t)0x00004000) /*!< bit 14 */
+#define NVIC_ISPR_SETPEND_15 ((uint32_t)0x00008000) /*!< bit 15 */
+#define NVIC_ISPR_SETPEND_16 ((uint32_t)0x00010000) /*!< bit 16 */
+#define NVIC_ISPR_SETPEND_17 ((uint32_t)0x00020000) /*!< bit 17 */
+#define NVIC_ISPR_SETPEND_18 ((uint32_t)0x00040000) /*!< bit 18 */
+#define NVIC_ISPR_SETPEND_19 ((uint32_t)0x00080000) /*!< bit 19 */
+#define NVIC_ISPR_SETPEND_20 ((uint32_t)0x00100000) /*!< bit 20 */
+#define NVIC_ISPR_SETPEND_21 ((uint32_t)0x00200000) /*!< bit 21 */
+#define NVIC_ISPR_SETPEND_22 ((uint32_t)0x00400000) /*!< bit 22 */
+#define NVIC_ISPR_SETPEND_23 ((uint32_t)0x00800000) /*!< bit 23 */
+#define NVIC_ISPR_SETPEND_24 ((uint32_t)0x01000000) /*!< bit 24 */
+#define NVIC_ISPR_SETPEND_25 ((uint32_t)0x02000000) /*!< bit 25 */
+#define NVIC_ISPR_SETPEND_26 ((uint32_t)0x04000000) /*!< bit 26 */
+#define NVIC_ISPR_SETPEND_27 ((uint32_t)0x08000000) /*!< bit 27 */
+#define NVIC_ISPR_SETPEND_28 ((uint32_t)0x10000000) /*!< bit 28 */
+#define NVIC_ISPR_SETPEND_29 ((uint32_t)0x20000000) /*!< bit 29 */
+#define NVIC_ISPR_SETPEND_30 ((uint32_t)0x40000000) /*!< bit 30 */
+#define NVIC_ISPR_SETPEND_31 ((uint32_t)0x80000000) /*!< bit 31 */
+
+/****************** Bit definition for NVIC_ICPR register *******************/
+#define NVIC_ICPR_CLRPEND ((uint32_t)0xFFFFFFFF) /*!< Interrupt clear-pending bits */
+#define NVIC_ICPR_CLRPEND_0 ((uint32_t)0x00000001) /*!< bit 0 */
+#define NVIC_ICPR_CLRPEND_1 ((uint32_t)0x00000002) /*!< bit 1 */
+#define NVIC_ICPR_CLRPEND_2 ((uint32_t)0x00000004) /*!< bit 2 */
+#define NVIC_ICPR_CLRPEND_3 ((uint32_t)0x00000008) /*!< bit 3 */
+#define NVIC_ICPR_CLRPEND_4 ((uint32_t)0x00000010) /*!< bit 4 */
+#define NVIC_ICPR_CLRPEND_5 ((uint32_t)0x00000020) /*!< bit 5 */
+#define NVIC_ICPR_CLRPEND_6 ((uint32_t)0x00000040) /*!< bit 6 */
+#define NVIC_ICPR_CLRPEND_7 ((uint32_t)0x00000080) /*!< bit 7 */
+#define NVIC_ICPR_CLRPEND_8 ((uint32_t)0x00000100) /*!< bit 8 */
+#define NVIC_ICPR_CLRPEND_9 ((uint32_t)0x00000200) /*!< bit 9 */
+#define NVIC_ICPR_CLRPEND_10 ((uint32_t)0x00000400) /*!< bit 10 */
+#define NVIC_ICPR_CLRPEND_11 ((uint32_t)0x00000800) /*!< bit 11 */
+#define NVIC_ICPR_CLRPEND_12 ((uint32_t)0x00001000) /*!< bit 12 */
+#define NVIC_ICPR_CLRPEND_13 ((uint32_t)0x00002000) /*!< bit 13 */
+#define NVIC_ICPR_CLRPEND_14 ((uint32_t)0x00004000) /*!< bit 14 */
+#define NVIC_ICPR_CLRPEND_15 ((uint32_t)0x00008000) /*!< bit 15 */
+#define NVIC_ICPR_CLRPEND_16 ((uint32_t)0x00010000) /*!< bit 16 */
+#define NVIC_ICPR_CLRPEND_17 ((uint32_t)0x00020000) /*!< bit 17 */
+#define NVIC_ICPR_CLRPEND_18 ((uint32_t)0x00040000) /*!< bit 18 */
+#define NVIC_ICPR_CLRPEND_19 ((uint32_t)0x00080000) /*!< bit 19 */
+#define NVIC_ICPR_CLRPEND_20 ((uint32_t)0x00100000) /*!< bit 20 */
+#define NVIC_ICPR_CLRPEND_21 ((uint32_t)0x00200000) /*!< bit 21 */
+#define NVIC_ICPR_CLRPEND_22 ((uint32_t)0x00400000) /*!< bit 22 */
+#define NVIC_ICPR_CLRPEND_23 ((uint32_t)0x00800000) /*!< bit 23 */
+#define NVIC_ICPR_CLRPEND_24 ((uint32_t)0x01000000) /*!< bit 24 */
+#define NVIC_ICPR_CLRPEND_25 ((uint32_t)0x02000000) /*!< bit 25 */
+#define NVIC_ICPR_CLRPEND_26 ((uint32_t)0x04000000) /*!< bit 26 */
+#define NVIC_ICPR_CLRPEND_27 ((uint32_t)0x08000000) /*!< bit 27 */
+#define NVIC_ICPR_CLRPEND_28 ((uint32_t)0x10000000) /*!< bit 28 */
+#define NVIC_ICPR_CLRPEND_29 ((uint32_t)0x20000000) /*!< bit 29 */
+#define NVIC_ICPR_CLRPEND_30 ((uint32_t)0x40000000) /*!< bit 30 */
+#define NVIC_ICPR_CLRPEND_31 ((uint32_t)0x80000000) /*!< bit 31 */
+
+/****************** Bit definition for NVIC_IABR register *******************/
+#define NVIC_IABR_ACTIVE ((uint32_t)0xFFFFFFFF) /*!< Interrupt active flags */
+#define NVIC_IABR_ACTIVE_0 ((uint32_t)0x00000001) /*!< bit 0 */
+#define NVIC_IABR_ACTIVE_1 ((uint32_t)0x00000002) /*!< bit 1 */
+#define NVIC_IABR_ACTIVE_2 ((uint32_t)0x00000004) /*!< bit 2 */
+#define NVIC_IABR_ACTIVE_3 ((uint32_t)0x00000008) /*!< bit 3 */
+#define NVIC_IABR_ACTIVE_4 ((uint32_t)0x00000010) /*!< bit 4 */
+#define NVIC_IABR_ACTIVE_5 ((uint32_t)0x00000020) /*!< bit 5 */
+#define NVIC_IABR_ACTIVE_6 ((uint32_t)0x00000040) /*!< bit 6 */
+#define NVIC_IABR_ACTIVE_7 ((uint32_t)0x00000080) /*!< bit 7 */
+#define NVIC_IABR_ACTIVE_8 ((uint32_t)0x00000100) /*!< bit 8 */
+#define NVIC_IABR_ACTIVE_9 ((uint32_t)0x00000200) /*!< bit 9 */
+#define NVIC_IABR_ACTIVE_10 ((uint32_t)0x00000400) /*!< bit 10 */
+#define NVIC_IABR_ACTIVE_11 ((uint32_t)0x00000800) /*!< bit 11 */
+#define NVIC_IABR_ACTIVE_12 ((uint32_t)0x00001000) /*!< bit 12 */
+#define NVIC_IABR_ACTIVE_13 ((uint32_t)0x00002000) /*!< bit 13 */
+#define NVIC_IABR_ACTIVE_14 ((uint32_t)0x00004000) /*!< bit 14 */
+#define NVIC_IABR_ACTIVE_15 ((uint32_t)0x00008000) /*!< bit 15 */
+#define NVIC_IABR_ACTIVE_16 ((uint32_t)0x00010000) /*!< bit 16 */
+#define NVIC_IABR_ACTIVE_17 ((uint32_t)0x00020000) /*!< bit 17 */
+#define NVIC_IABR_ACTIVE_18 ((uint32_t)0x00040000) /*!< bit 18 */
+#define NVIC_IABR_ACTIVE_19 ((uint32_t)0x00080000) /*!< bit 19 */
+#define NVIC_IABR_ACTIVE_20 ((uint32_t)0x00100000) /*!< bit 20 */
+#define NVIC_IABR_ACTIVE_21 ((uint32_t)0x00200000) /*!< bit 21 */
+#define NVIC_IABR_ACTIVE_22 ((uint32_t)0x00400000) /*!< bit 22 */
+#define NVIC_IABR_ACTIVE_23 ((uint32_t)0x00800000) /*!< bit 23 */
+#define NVIC_IABR_ACTIVE_24 ((uint32_t)0x01000000) /*!< bit 24 */
+#define NVIC_IABR_ACTIVE_25 ((uint32_t)0x02000000) /*!< bit 25 */
+#define NVIC_IABR_ACTIVE_26 ((uint32_t)0x04000000) /*!< bit 26 */
+#define NVIC_IABR_ACTIVE_27 ((uint32_t)0x08000000) /*!< bit 27 */
+#define NVIC_IABR_ACTIVE_28 ((uint32_t)0x10000000) /*!< bit 28 */
+#define NVIC_IABR_ACTIVE_29 ((uint32_t)0x20000000) /*!< bit 29 */
+#define NVIC_IABR_ACTIVE_30 ((uint32_t)0x40000000) /*!< bit 30 */
+#define NVIC_IABR_ACTIVE_31 ((uint32_t)0x80000000) /*!< bit 31 */
+
+/****************** Bit definition for NVIC_PRI0 register *******************/
+#define NVIC_IPR0_PRI_0 ((uint32_t)0x000000FF) /*!< Priority of interrupt 0 */
+#define NVIC_IPR0_PRI_1 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 1 */
+#define NVIC_IPR0_PRI_2 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 2 */
+#define NVIC_IPR0_PRI_3 ((uint32_t)0xFF000000) /*!< Priority of interrupt 3 */
+
+/****************** Bit definition for NVIC_PRI1 register *******************/
+#define NVIC_IPR1_PRI_4 ((uint32_t)0x000000FF) /*!< Priority of interrupt 4 */
+#define NVIC_IPR1_PRI_5 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 5 */
+#define NVIC_IPR1_PRI_6 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 6 */
+#define NVIC_IPR1_PRI_7 ((uint32_t)0xFF000000) /*!< Priority of interrupt 7 */
+
+/****************** Bit definition for NVIC_PRI2 register *******************/
+#define NVIC_IPR2_PRI_8 ((uint32_t)0x000000FF) /*!< Priority of interrupt 8 */
+#define NVIC_IPR2_PRI_9 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 9 */
+#define NVIC_IPR2_PRI_10 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 10 */
+#define NVIC_IPR2_PRI_11 ((uint32_t)0xFF000000) /*!< Priority of interrupt 11 */
+
+/****************** Bit definition for NVIC_PRI3 register *******************/
+#define NVIC_IPR3_PRI_12 ((uint32_t)0x000000FF) /*!< Priority of interrupt 12 */
+#define NVIC_IPR3_PRI_13 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 13 */
+#define NVIC_IPR3_PRI_14 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 14 */
+#define NVIC_IPR3_PRI_15 ((uint32_t)0xFF000000) /*!< Priority of interrupt 15 */
+
+/****************** Bit definition for NVIC_PRI4 register *******************/
+#define NVIC_IPR4_PRI_16 ((uint32_t)0x000000FF) /*!< Priority of interrupt 16 */
+#define NVIC_IPR4_PRI_17 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 17 */
+#define NVIC_IPR4_PRI_18 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 18 */
+#define NVIC_IPR4_PRI_19 ((uint32_t)0xFF000000) /*!< Priority of interrupt 19 */
+
+/****************** Bit definition for NVIC_PRI5 register *******************/
+#define NVIC_IPR5_PRI_20 ((uint32_t)0x000000FF) /*!< Priority of interrupt 20 */
+#define NVIC_IPR5_PRI_21 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 21 */
+#define NVIC_IPR5_PRI_22 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 22 */
+#define NVIC_IPR5_PRI_23 ((uint32_t)0xFF000000) /*!< Priority of interrupt 23 */
+
+/****************** Bit definition for NVIC_PRI6 register *******************/
+#define NVIC_IPR6_PRI_24 ((uint32_t)0x000000FF) /*!< Priority of interrupt 24 */
+#define NVIC_IPR6_PRI_25 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 25 */
+#define NVIC_IPR6_PRI_26 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 26 */
+#define NVIC_IPR6_PRI_27 ((uint32_t)0xFF000000) /*!< Priority of interrupt 27 */
+
+/****************** Bit definition for NVIC_PRI7 register *******************/
+#define NVIC_IPR7_PRI_28 ((uint32_t)0x000000FF) /*!< Priority of interrupt 28 */
+#define NVIC_IPR7_PRI_29 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 29 */
+#define NVIC_IPR7_PRI_30 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 30 */
+#define NVIC_IPR7_PRI_31 ((uint32_t)0xFF000000) /*!< Priority of interrupt 31 */
+
+/****************** Bit definition for SCB_CPUID register *******************/
+#define SCB_CPUID_REVISION ((uint32_t)0x0000000F) /*!< Implementation defined revision number */
+#define SCB_CPUID_PARTNO ((uint32_t)0x0000FFF0) /*!< Number of processor within family */
+#define SCB_CPUID_Constant ((uint32_t)0x000F0000) /*!< Reads as 0x0F */
+#define SCB_CPUID_VARIANT ((uint32_t)0x00F00000) /*!< Implementation defined variant number */
+#define SCB_CPUID_IMPLEMENTER ((uint32_t)0xFF000000) /*!< Implementer code. ARM is 0x41 */
+
+/******************* Bit definition for SCB_ICSR register *******************/
+#define SCB_ICSR_VECTACTIVE ((uint32_t)0x000001FF) /*!< Active ISR number field */
+#define SCB_ICSR_RETTOBASE ((uint32_t)0x00000800) /*!< All active exceptions minus the IPSR_current_exception yields the empty set */
+#define SCB_ICSR_VECTPENDING ((uint32_t)0x003FF000) /*!< Pending ISR number field */
+#define SCB_ICSR_ISRPENDING ((uint32_t)0x00400000) /*!< Interrupt pending flag */
+#define SCB_ICSR_ISRPREEMPT ((uint32_t)0x00800000) /*!< It indicates that a pending interrupt becomes active in the next running cycle */
+#define SCB_ICSR_PENDSTCLR ((uint32_t)0x02000000) /*!< Clear pending SysTick bit */
+#define SCB_ICSR_PENDSTSET ((uint32_t)0x04000000) /*!< Set pending SysTick bit */
+#define SCB_ICSR_PENDSVCLR ((uint32_t)0x08000000) /*!< Clear pending pendSV bit */
+#define SCB_ICSR_PENDSVSET ((uint32_t)0x10000000) /*!< Set pending pendSV bit */
+#define SCB_ICSR_NMIPENDSET ((uint32_t)0x80000000) /*!< Set pending NMI bit */
+
+/******************* Bit definition for SCB_VTOR register *******************/
+#define SCB_VTOR_TBLOFF ((uint32_t)0x1FFFFF80) /*!< Vector table base offset field */
+#define SCB_VTOR_TBLBASE ((uint32_t)0x20000000) /*!< Table base in code(0) or RAM(1) */
+
+/*!<***************** Bit definition for SCB_AIRCR register *******************/
+#define SCB_AIRCR_VECTRESET ((uint32_t)0x00000001) /*!< System Reset bit */
+#define SCB_AIRCR_VECTCLRACTIVE ((uint32_t)0x00000002) /*!< Clear active vector bit */
+#define SCB_AIRCR_SYSRESETREQ ((uint32_t)0x00000004) /*!< Requests chip control logic to generate a reset */
+
+#define SCB_AIRCR_PRIGROUP ((uint32_t)0x00000700) /*!< PRIGROUP[2:0] bits (Priority group) */
+#define SCB_AIRCR_PRIGROUP_0 ((uint32_t)0x00000100) /*!< Bit 0 */
+#define SCB_AIRCR_PRIGROUP_1 ((uint32_t)0x00000200) /*!< Bit 1 */
+#define SCB_AIRCR_PRIGROUP_2 ((uint32_t)0x00000400) /*!< Bit 2 */
+
+/* prority group configuration */
+#define SCB_AIRCR_PRIGROUP0 ((uint32_t)0x00000000) /*!< Priority group=0 (7 bits of pre-emption priority, 1 bit of subpriority) */
+#define SCB_AIRCR_PRIGROUP1 ((uint32_t)0x00000100) /*!< Priority group=1 (6 bits of pre-emption priority, 2 bits of subpriority) */
+#define SCB_AIRCR_PRIGROUP2 ((uint32_t)0x00000200) /*!< Priority group=2 (5 bits of pre-emption priority, 3 bits of subpriority) */
+#define SCB_AIRCR_PRIGROUP3 ((uint32_t)0x00000300) /*!< Priority group=3 (4 bits of pre-emption priority, 4 bits of subpriority) */
+#define SCB_AIRCR_PRIGROUP4 ((uint32_t)0x00000400) /*!< Priority group=4 (3 bits of pre-emption priority, 5 bits of subpriority) */
+#define SCB_AIRCR_PRIGROUP5 ((uint32_t)0x00000500) /*!< Priority group=5 (2 bits of pre-emption priority, 6 bits of subpriority) */
+#define SCB_AIRCR_PRIGROUP6 ((uint32_t)0x00000600) /*!< Priority group=6 (1 bit of pre-emption priority, 7 bits of subpriority) */
+#define SCB_AIRCR_PRIGROUP7 ((uint32_t)0x00000700) /*!< Priority group=7 (no pre-emption priority, 8 bits of subpriority) */
+
+#define SCB_AIRCR_ENDIANESS ((uint32_t)0x00008000) /*!< Data endianness bit */
+#define SCB_AIRCR_VECTKEY ((uint32_t)0xFFFF0000) /*!< Register key (VECTKEY) - Reads as 0xFA05 (VECTKEYSTAT) */
+
+/******************* Bit definition for SCB_SCR register ********************/
+#define SCB_SCR_SLEEPONEXIT ((uint8_t)0x02) /*!< Sleep on exit bit */
+#define SCB_SCR_SLEEPDEEP ((uint8_t)0x04) /*!< Sleep deep bit */
+#define SCB_SCR_SEVONPEND ((uint8_t)0x10) /*!< Wake up from WFE */
+
+/******************** Bit definition for SCB_CCR register *******************/
+#define SCB_CCR_NONBASETHRDENA ((uint16_t)0x0001) /*!< Thread mode can be entered from any level in Handler mode by controlled return value */
+#define SCB_CCR_USERSETMPEND ((uint16_t)0x0002) /*!< Enables user code to write the Software Trigger Interrupt register to trigger (pend) a Main exception */
+#define SCB_CCR_UNALIGN_TRP ((uint16_t)0x0008) /*!< Trap for unaligned access */
+#define SCB_CCR_DIV_0_TRP ((uint16_t)0x0010) /*!< Trap on Divide by 0 */
+#define SCB_CCR_BFHFNMIGN ((uint16_t)0x0100) /*!< Handlers running at priority -1 and -2 */
+#define SCB_CCR_STKALIGN ((uint16_t)0x0200) /*!< On exception entry, the SP used prior to the exception is adjusted to be 8-byte aligned */
+
+/******************* Bit definition for SCB_SHPR register ********************/
+#define SCB_SHPR_PRI_N ((uint32_t)0x000000FF) /*!< Priority of system handler 4,8, and 12. Mem Manage, reserved and Debug Monitor */
+#define SCB_SHPR_PRI_N1 ((uint32_t)0x0000FF00) /*!< Priority of system handler 5,9, and 13. Bus Fault, reserved and reserved */
+#define SCB_SHPR_PRI_N2 ((uint32_t)0x00FF0000) /*!< Priority of system handler 6,10, and 14. Usage Fault, reserved and PendSV */
+#define SCB_SHPR_PRI_N3 ((uint32_t)0xFF000000) /*!< Priority of system handler 7,11, and 15. Reserved, SVCall and SysTick */
+
+/****************** Bit definition for SCB_SHCSR register *******************/
+#define SCB_SHCSR_MEMFAULTACT ((uint32_t)0x00000001) /*!< MemManage is active */
+#define SCB_SHCSR_BUSFAULTACT ((uint32_t)0x00000002) /*!< BusFault is active */
+#define SCB_SHCSR_USGFAULTACT ((uint32_t)0x00000008) /*!< UsageFault is active */
+#define SCB_SHCSR_SVCALLACT ((uint32_t)0x00000080) /*!< SVCall is active */
+#define SCB_SHCSR_MONITORACT ((uint32_t)0x00000100) /*!< Monitor is active */
+#define SCB_SHCSR_PENDSVACT ((uint32_t)0x00000400) /*!< PendSV is active */
+#define SCB_SHCSR_SYSTICKACT ((uint32_t)0x00000800) /*!< SysTick is active */
+#define SCB_SHCSR_USGFAULTPENDED ((uint32_t)0x00001000) /*!< Usage Fault is pended */
+#define SCB_SHCSR_MEMFAULTPENDED ((uint32_t)0x00002000) /*!< MemManage is pended */
+#define SCB_SHCSR_BUSFAULTPENDED ((uint32_t)0x00004000) /*!< Bus Fault is pended */
+#define SCB_SHCSR_SVCALLPENDED ((uint32_t)0x00008000) /*!< SVCall is pended */
+#define SCB_SHCSR_MEMFAULTENA ((uint32_t)0x00010000) /*!< MemManage enable */
+#define SCB_SHCSR_BUSFAULTENA ((uint32_t)0x00020000) /*!< Bus Fault enable */
+#define SCB_SHCSR_USGFAULTENA ((uint32_t)0x00040000) /*!< UsageFault enable */
+
+/******************* Bit definition for SCB_CFSR register *******************/
+/*!< MFSR */
+#define SCB_CFSR_IACCVIOL ((uint32_t)0x00000001) /*!< Instruction access violation */
+#define SCB_CFSR_DACCVIOL ((uint32_t)0x00000002) /*!< Data access violation */
+#define SCB_CFSR_MUNSTKERR ((uint32_t)0x00000008) /*!< Unstacking error */
+#define SCB_CFSR_MSTKERR ((uint32_t)0x00000010) /*!< Stacking error */
+#define SCB_CFSR_MMARVALID ((uint32_t)0x00000080) /*!< Memory Manage Address Register address valid flag */
+/*!< BFSR */
+#define SCB_CFSR_IBUSERR ((uint32_t)0x00000100) /*!< Instruction bus error flag */
+#define SCB_CFSR_PRECISERR ((uint32_t)0x00000200) /*!< Precise data bus error */
+#define SCB_CFSR_IMPRECISERR ((uint32_t)0x00000400) /*!< Imprecise data bus error */
+#define SCB_CFSR_UNSTKERR ((uint32_t)0x00000800) /*!< Unstacking error */
+#define SCB_CFSR_STKERR ((uint32_t)0x00001000) /*!< Stacking error */
+#define SCB_CFSR_BFARVALID ((uint32_t)0x00008000) /*!< Bus Fault Address Register address valid flag */
+/*!< UFSR */
+#define SCB_CFSR_UNDEFINSTR ((uint32_t)0x00010000) /*!< The processor attempt to execute an undefined instruction */
+#define SCB_CFSR_INVSTATE ((uint32_t)0x00020000) /*!< Invalid combination of EPSR and instruction */
+#define SCB_CFSR_INVPC ((uint32_t)0x00040000) /*!< Attempt to load EXC_RETURN into pc illegally */
+#define SCB_CFSR_NOCP ((uint32_t)0x00080000) /*!< Attempt to use a coprocessor instruction */
+#define SCB_CFSR_UNALIGNED ((uint32_t)0x01000000) /*!< Fault occurs when there is an attempt to make an unaligned memory access */
+#define SCB_CFSR_DIVBYZERO ((uint32_t)0x02000000) /*!< Fault occurs when SDIV or DIV instruction is used with a divisor of 0 */
+
+/******************* Bit definition for SCB_HFSR register *******************/
+#define SCB_HFSR_VECTTBL ((uint32_t)0x00000002) /*!< Fault occurs because of vector table read on exception processing */
+#define SCB_HFSR_FORCED ((uint32_t)0x40000000) /*!< Hard Fault activated when a configurable Fault was received and cannot activate */
+#define SCB_HFSR_DEBUGEVT ((uint32_t)0x80000000) /*!< Fault related to debug */
+
+/******************* Bit definition for SCB_DFSR register *******************/
+#define SCB_DFSR_HALTED ((uint8_t)0x01) /*!< Halt request flag */
+#define SCB_DFSR_BKPT ((uint8_t)0x02) /*!< BKPT flag */
+#define SCB_DFSR_DWTTRAP ((uint8_t)0x04) /*!< Data Watchpoint and Trace (DWT) flag */
+#define SCB_DFSR_VCATCH ((uint8_t)0x08) /*!< Vector catch flag */
+#define SCB_DFSR_EXTERNAL ((uint8_t)0x10) /*!< External debug request flag */
+
+/******************* Bit definition for SCB_MMFAR register ******************/
+#define SCB_MMFAR_ADDRESS ((uint32_t)0xFFFFFFFF) /*!< Mem Manage fault address field */
+
+/******************* Bit definition for SCB_BFAR register *******************/
+#define SCB_BFAR_ADDRESS ((uint32_t)0xFFFFFFFF) /*!< Bus fault address field */
+
+/******************* Bit definition for SCB_afsr register *******************/
+#define SCB_AFSR_IMPDEF ((uint32_t)0xFFFFFFFF) /*!< Implementation defined */
+
+/******************************************************************************/
+/* */
+/* External Interrupt/Event Controller (EXTI) */
+/* */
+/******************************************************************************/
+/******************* Bit definition for EXTI_IMR register *******************/
+#define EXTI_IMR_MR0_Pos (0U)
+#define EXTI_IMR_MR0_Msk (0x1U << EXTI_IMR_MR0_Pos) /*!< 0x00000001 */
+#define EXTI_IMR_MR0 EXTI_IMR_MR0_Msk /*!< Interrupt Mask on line 0 */
+#define EXTI_IMR_MR1_Pos (1U)
+#define EXTI_IMR_MR1_Msk (0x1U << EXTI_IMR_MR1_Pos) /*!< 0x00000002 */
+#define EXTI_IMR_MR1 EXTI_IMR_MR1_Msk /*!< Interrupt Mask on line 1 */
+#define EXTI_IMR_MR2_Pos (2U)
+#define EXTI_IMR_MR2_Msk (0x1U << EXTI_IMR_MR2_Pos) /*!< 0x00000004 */
+#define EXTI_IMR_MR2 EXTI_IMR_MR2_Msk /*!< Interrupt Mask on line 2 */
+#define EXTI_IMR_MR3_Pos (3U)
+#define EXTI_IMR_MR3_Msk (0x1U << EXTI_IMR_MR3_Pos) /*!< 0x00000008 */
+#define EXTI_IMR_MR3 EXTI_IMR_MR3_Msk /*!< Interrupt Mask on line 3 */
+#define EXTI_IMR_MR4_Pos (4U)
+#define EXTI_IMR_MR4_Msk (0x1U << EXTI_IMR_MR4_Pos) /*!< 0x00000010 */
+#define EXTI_IMR_MR4 EXTI_IMR_MR4_Msk /*!< Interrupt Mask on line 4 */
+#define EXTI_IMR_MR5_Pos (5U)
+#define EXTI_IMR_MR5_Msk (0x1U << EXTI_IMR_MR5_Pos) /*!< 0x00000020 */
+#define EXTI_IMR_MR5 EXTI_IMR_MR5_Msk /*!< Interrupt Mask on line 5 */
+#define EXTI_IMR_MR6_Pos (6U)
+#define EXTI_IMR_MR6_Msk (0x1U << EXTI_IMR_MR6_Pos) /*!< 0x00000040 */
+#define EXTI_IMR_MR6 EXTI_IMR_MR6_Msk /*!< Interrupt Mask on line 6 */
+#define EXTI_IMR_MR7_Pos (7U)
+#define EXTI_IMR_MR7_Msk (0x1U << EXTI_IMR_MR7_Pos) /*!< 0x00000080 */
+#define EXTI_IMR_MR7 EXTI_IMR_MR7_Msk /*!< Interrupt Mask on line 7 */
+#define EXTI_IMR_MR8_Pos (8U)
+#define EXTI_IMR_MR8_Msk (0x1U << EXTI_IMR_MR8_Pos) /*!< 0x00000100 */
+#define EXTI_IMR_MR8 EXTI_IMR_MR8_Msk /*!< Interrupt Mask on line 8 */
+#define EXTI_IMR_MR9_Pos (9U)
+#define EXTI_IMR_MR9_Msk (0x1U << EXTI_IMR_MR9_Pos) /*!< 0x00000200 */
+#define EXTI_IMR_MR9 EXTI_IMR_MR9_Msk /*!< Interrupt Mask on line 9 */
+#define EXTI_IMR_MR10_Pos (10U)
+#define EXTI_IMR_MR10_Msk (0x1U << EXTI_IMR_MR10_Pos) /*!< 0x00000400 */
+#define EXTI_IMR_MR10 EXTI_IMR_MR10_Msk /*!< Interrupt Mask on line 10 */
+#define EXTI_IMR_MR11_Pos (11U)
+#define EXTI_IMR_MR11_Msk (0x1U << EXTI_IMR_MR11_Pos) /*!< 0x00000800 */
+#define EXTI_IMR_MR11 EXTI_IMR_MR11_Msk /*!< Interrupt Mask on line 11 */
+#define EXTI_IMR_MR12_Pos (12U)
+#define EXTI_IMR_MR12_Msk (0x1U << EXTI_IMR_MR12_Pos) /*!< 0x00001000 */
+#define EXTI_IMR_MR12 EXTI_IMR_MR12_Msk /*!< Interrupt Mask on line 12 */
+#define EXTI_IMR_MR13_Pos (13U)
+#define EXTI_IMR_MR13_Msk (0x1U << EXTI_IMR_MR13_Pos) /*!< 0x00002000 */
+#define EXTI_IMR_MR13 EXTI_IMR_MR13_Msk /*!< Interrupt Mask on line 13 */
+#define EXTI_IMR_MR14_Pos (14U)
+#define EXTI_IMR_MR14_Msk (0x1U << EXTI_IMR_MR14_Pos) /*!< 0x00004000 */
+#define EXTI_IMR_MR14 EXTI_IMR_MR14_Msk /*!< Interrupt Mask on line 14 */
+#define EXTI_IMR_MR15_Pos (15U)
+#define EXTI_IMR_MR15_Msk (0x1U << EXTI_IMR_MR15_Pos) /*!< 0x00008000 */
+#define EXTI_IMR_MR15 EXTI_IMR_MR15_Msk /*!< Interrupt Mask on line 15 */
+#define EXTI_IMR_MR17_Pos (17U)
+#define EXTI_IMR_MR17_Msk (0x1U << EXTI_IMR_MR17_Pos) /*!< 0x00020000 */
+#define EXTI_IMR_MR17 EXTI_IMR_MR17_Msk /*!< Interrupt Mask on line 17 */
+#define EXTI_IMR_MR18_Pos (18U)
+#define EXTI_IMR_MR18_Msk (0x1U << EXTI_IMR_MR18_Pos) /*!< 0x00040000 */
+#define EXTI_IMR_MR18 EXTI_IMR_MR18_Msk /*!< Interrupt Mask on line 18 */
+#define EXTI_IMR_MR19_Pos (19U)
+#define EXTI_IMR_MR19_Msk (0x1U << EXTI_IMR_MR19_Pos) /*!< 0x00080000 */
+#define EXTI_IMR_MR19 EXTI_IMR_MR19_Msk /*!< Interrupt Mask on line 19 */
+#define EXTI_IMR_MR23_Pos (23U)
+#define EXTI_IMR_MR23_Msk (0x1U << EXTI_IMR_MR23_Pos) /*!< 0x00800000 */
+#define EXTI_IMR_MR23 EXTI_IMR_MR23_Msk /*!< Interrupt Mask on line 23 */
+
+/* References Defines */
+#define EXTI_IMR_IM0 EXTI_IMR_MR0
+#define EXTI_IMR_IM1 EXTI_IMR_MR1
+#define EXTI_IMR_IM2 EXTI_IMR_MR2
+#define EXTI_IMR_IM3 EXTI_IMR_MR3
+#define EXTI_IMR_IM4 EXTI_IMR_MR4
+#define EXTI_IMR_IM5 EXTI_IMR_MR5
+#define EXTI_IMR_IM6 EXTI_IMR_MR6
+#define EXTI_IMR_IM7 EXTI_IMR_MR7
+#define EXTI_IMR_IM8 EXTI_IMR_MR8
+#define EXTI_IMR_IM9 EXTI_IMR_MR9
+#define EXTI_IMR_IM10 EXTI_IMR_MR10
+#define EXTI_IMR_IM11 EXTI_IMR_MR11
+#define EXTI_IMR_IM12 EXTI_IMR_MR12
+#define EXTI_IMR_IM13 EXTI_IMR_MR13
+#define EXTI_IMR_IM14 EXTI_IMR_MR14
+#define EXTI_IMR_IM15 EXTI_IMR_MR15
+#define EXTI_IMR_IM17 EXTI_IMR_MR17
+#define EXTI_IMR_IM18 EXTI_IMR_MR18
+#define EXTI_IMR_IM19 EXTI_IMR_MR19
+#define EXTI_IMR_IM23 EXTI_IMR_MR23
+
+#define EXTI_IMR_IM_Pos (0U)
+#define EXTI_IMR_IM_Msk (0x8EFFFFU << EXTI_IMR_IM_Pos) /*!< 0x008EFFFF */
+#define EXTI_IMR_IM EXTI_IMR_IM_Msk /*!< Interrupt Mask All */
+
+
+/****************** Bit definition for EXTI_EMR register ********************/
+#define EXTI_EMR_MR0_Pos (0U)
+#define EXTI_EMR_MR0_Msk (0x1U << EXTI_EMR_MR0_Pos) /*!< 0x00000001 */
+#define EXTI_EMR_MR0 EXTI_EMR_MR0_Msk /*!< Event Mask on line 0 */
+#define EXTI_EMR_MR1_Pos (1U)
+#define EXTI_EMR_MR1_Msk (0x1U << EXTI_EMR_MR1_Pos) /*!< 0x00000002 */
+#define EXTI_EMR_MR1 EXTI_EMR_MR1_Msk /*!< Event Mask on line 1 */
+#define EXTI_EMR_MR2_Pos (2U)
+#define EXTI_EMR_MR2_Msk (0x1U << EXTI_EMR_MR2_Pos) /*!< 0x00000004 */
+#define EXTI_EMR_MR2 EXTI_EMR_MR2_Msk /*!< Event Mask on line 2 */
+#define EXTI_EMR_MR3_Pos (3U)
+#define EXTI_EMR_MR3_Msk (0x1U << EXTI_EMR_MR3_Pos) /*!< 0x00000008 */
+#define EXTI_EMR_MR3 EXTI_EMR_MR3_Msk /*!< Event Mask on line 3 */
+#define EXTI_EMR_MR4_Pos (4U)
+#define EXTI_EMR_MR4_Msk (0x1U << EXTI_EMR_MR4_Pos) /*!< 0x00000010 */
+#define EXTI_EMR_MR4 EXTI_EMR_MR4_Msk /*!< Event Mask on line 4 */
+#define EXTI_EMR_MR5_Pos (5U)
+#define EXTI_EMR_MR5_Msk (0x1U << EXTI_EMR_MR5_Pos) /*!< 0x00000020 */
+#define EXTI_EMR_MR5 EXTI_EMR_MR5_Msk /*!< Event Mask on line 5 */
+#define EXTI_EMR_MR6_Pos (6U)
+#define EXTI_EMR_MR6_Msk (0x1U << EXTI_EMR_MR6_Pos) /*!< 0x00000040 */
+#define EXTI_EMR_MR6 EXTI_EMR_MR6_Msk /*!< Event Mask on line 6 */
+#define EXTI_EMR_MR7_Pos (7U)
+#define EXTI_EMR_MR7_Msk (0x1U << EXTI_EMR_MR7_Pos) /*!< 0x00000080 */
+#define EXTI_EMR_MR7 EXTI_EMR_MR7_Msk /*!< Event Mask on line 7 */
+#define EXTI_EMR_MR8_Pos (8U)
+#define EXTI_EMR_MR8_Msk (0x1U << EXTI_EMR_MR8_Pos) /*!< 0x00000100 */
+#define EXTI_EMR_MR8 EXTI_EMR_MR8_Msk /*!< Event Mask on line 8 */
+#define EXTI_EMR_MR9_Pos (9U)
+#define EXTI_EMR_MR9_Msk (0x1U << EXTI_EMR_MR9_Pos) /*!< 0x00000200 */
+#define EXTI_EMR_MR9 EXTI_EMR_MR9_Msk /*!< Event Mask on line 9 */
+#define EXTI_EMR_MR10_Pos (10U)
+#define EXTI_EMR_MR10_Msk (0x1U << EXTI_EMR_MR10_Pos) /*!< 0x00000400 */
+#define EXTI_EMR_MR10 EXTI_EMR_MR10_Msk /*!< Event Mask on line 10 */
+#define EXTI_EMR_MR11_Pos (11U)
+#define EXTI_EMR_MR11_Msk (0x1U << EXTI_EMR_MR11_Pos) /*!< 0x00000800 */
+#define EXTI_EMR_MR11 EXTI_EMR_MR11_Msk /*!< Event Mask on line 11 */
+#define EXTI_EMR_MR12_Pos (12U)
+#define EXTI_EMR_MR12_Msk (0x1U << EXTI_EMR_MR12_Pos) /*!< 0x00001000 */
+#define EXTI_EMR_MR12 EXTI_EMR_MR12_Msk /*!< Event Mask on line 12 */
+#define EXTI_EMR_MR13_Pos (13U)
+#define EXTI_EMR_MR13_Msk (0x1U << EXTI_EMR_MR13_Pos) /*!< 0x00002000 */
+#define EXTI_EMR_MR13 EXTI_EMR_MR13_Msk /*!< Event Mask on line 13 */
+#define EXTI_EMR_MR14_Pos (14U)
+#define EXTI_EMR_MR14_Msk (0x1U << EXTI_EMR_MR14_Pos) /*!< 0x00004000 */
+#define EXTI_EMR_MR14 EXTI_EMR_MR14_Msk /*!< Event Mask on line 14 */
+#define EXTI_EMR_MR15_Pos (15U)
+#define EXTI_EMR_MR15_Msk (0x1U << EXTI_EMR_MR15_Pos) /*!< 0x00008000 */
+#define EXTI_EMR_MR15 EXTI_EMR_MR15_Msk /*!< Event Mask on line 15 */
+#define EXTI_EMR_MR17_Pos (17U)
+#define EXTI_EMR_MR17_Msk (0x1U << EXTI_EMR_MR17_Pos) /*!< 0x00020000 */
+#define EXTI_EMR_MR17 EXTI_EMR_MR17_Msk /*!< Event Mask on line 17 */
+#define EXTI_EMR_MR18_Pos (18U)
+#define EXTI_EMR_MR18_Msk (0x1U << EXTI_EMR_MR18_Pos) /*!< 0x00040000 */
+#define EXTI_EMR_MR18 EXTI_EMR_MR18_Msk /*!< Event Mask on line 18 */
+#define EXTI_EMR_MR19_Pos (19U)
+#define EXTI_EMR_MR19_Msk (0x1U << EXTI_EMR_MR19_Pos) /*!< 0x00080000 */
+#define EXTI_EMR_MR19 EXTI_EMR_MR19_Msk /*!< Event Mask on line 19 */
+#define EXTI_EMR_MR23_Pos (23U)
+#define EXTI_EMR_MR23_Msk (0x1U << EXTI_EMR_MR23_Pos) /*!< 0x00800000 */
+#define EXTI_EMR_MR23 EXTI_EMR_MR23_Msk /*!< Event Mask on line 23 */
+
+/* References Defines */
+#define EXTI_EMR_EM0 EXTI_EMR_MR0
+#define EXTI_EMR_EM1 EXTI_EMR_MR1
+#define EXTI_EMR_EM2 EXTI_EMR_MR2
+#define EXTI_EMR_EM3 EXTI_EMR_MR3
+#define EXTI_EMR_EM4 EXTI_EMR_MR4
+#define EXTI_EMR_EM5 EXTI_EMR_MR5
+#define EXTI_EMR_EM6 EXTI_EMR_MR6
+#define EXTI_EMR_EM7 EXTI_EMR_MR7
+#define EXTI_EMR_EM8 EXTI_EMR_MR8
+#define EXTI_EMR_EM9 EXTI_EMR_MR9
+#define EXTI_EMR_EM10 EXTI_EMR_MR10
+#define EXTI_EMR_EM11 EXTI_EMR_MR11
+#define EXTI_EMR_EM12 EXTI_EMR_MR12
+#define EXTI_EMR_EM13 EXTI_EMR_MR13
+#define EXTI_EMR_EM14 EXTI_EMR_MR14
+#define EXTI_EMR_EM15 EXTI_EMR_MR15
+#define EXTI_EMR_EM17 EXTI_EMR_MR17
+#define EXTI_EMR_EM18 EXTI_EMR_MR18
+#define EXTI_EMR_EM19 EXTI_EMR_MR19
+#define EXTI_EMR_EM23 EXTI_EMR_MR23
+
+/******************* Bit definition for EXTI_RTSR register ******************/
+#define EXTI_RTSR_TR0_Pos (0U)
+#define EXTI_RTSR_TR0_Msk (0x1U << EXTI_RTSR_TR0_Pos) /*!< 0x00000001 */
+#define EXTI_RTSR_TR0 EXTI_RTSR_TR0_Msk /*!< Rising trigger event configuration bit of line 0 */
+#define EXTI_RTSR_TR1_Pos (1U)
+#define EXTI_RTSR_TR1_Msk (0x1U << EXTI_RTSR_TR1_Pos) /*!< 0x00000002 */
+#define EXTI_RTSR_TR1 EXTI_RTSR_TR1_Msk /*!< Rising trigger event configuration bit of line 1 */
+#define EXTI_RTSR_TR2_Pos (2U)
+#define EXTI_RTSR_TR2_Msk (0x1U << EXTI_RTSR_TR2_Pos) /*!< 0x00000004 */
+#define EXTI_RTSR_TR2 EXTI_RTSR_TR2_Msk /*!< Rising trigger event configuration bit of line 2 */
+#define EXTI_RTSR_TR3_Pos (3U)
+#define EXTI_RTSR_TR3_Msk (0x1U << EXTI_RTSR_TR3_Pos) /*!< 0x00000008 */
+#define EXTI_RTSR_TR3 EXTI_RTSR_TR3_Msk /*!< Rising trigger event configuration bit of line 3 */
+#define EXTI_RTSR_TR4_Pos (4U)
+#define EXTI_RTSR_TR4_Msk (0x1U << EXTI_RTSR_TR4_Pos) /*!< 0x00000010 */
+#define EXTI_RTSR_TR4 EXTI_RTSR_TR4_Msk /*!< Rising trigger event configuration bit of line 4 */
+#define EXTI_RTSR_TR5_Pos (5U)
+#define EXTI_RTSR_TR5_Msk (0x1U << EXTI_RTSR_TR5_Pos) /*!< 0x00000020 */
+#define EXTI_RTSR_TR5 EXTI_RTSR_TR5_Msk /*!< Rising trigger event configuration bit of line 5 */
+#define EXTI_RTSR_TR6_Pos (6U)
+#define EXTI_RTSR_TR6_Msk (0x1U << EXTI_RTSR_TR6_Pos) /*!< 0x00000040 */
+#define EXTI_RTSR_TR6 EXTI_RTSR_TR6_Msk /*!< Rising trigger event configuration bit of line 6 */
+#define EXTI_RTSR_TR7_Pos (7U)
+#define EXTI_RTSR_TR7_Msk (0x1U << EXTI_RTSR_TR7_Pos) /*!< 0x00000080 */
+#define EXTI_RTSR_TR7 EXTI_RTSR_TR7_Msk /*!< Rising trigger event configuration bit of line 7 */
+#define EXTI_RTSR_TR8_Pos (8U)
+#define EXTI_RTSR_TR8_Msk (0x1U << EXTI_RTSR_TR8_Pos) /*!< 0x00000100 */
+#define EXTI_RTSR_TR8 EXTI_RTSR_TR8_Msk /*!< Rising trigger event configuration bit of line 8 */
+#define EXTI_RTSR_TR9_Pos (9U)
+#define EXTI_RTSR_TR9_Msk (0x1U << EXTI_RTSR_TR9_Pos) /*!< 0x00000200 */
+#define EXTI_RTSR_TR9 EXTI_RTSR_TR9_Msk /*!< Rising trigger event configuration bit of line 9 */
+#define EXTI_RTSR_TR10_Pos (10U)
+#define EXTI_RTSR_TR10_Msk (0x1U << EXTI_RTSR_TR10_Pos) /*!< 0x00000400 */
+#define EXTI_RTSR_TR10 EXTI_RTSR_TR10_Msk /*!< Rising trigger event configuration bit of line 10 */
+#define EXTI_RTSR_TR11_Pos (11U)
+#define EXTI_RTSR_TR11_Msk (0x1U << EXTI_RTSR_TR11_Pos) /*!< 0x00000800 */
+#define EXTI_RTSR_TR11 EXTI_RTSR_TR11_Msk /*!< Rising trigger event configuration bit of line 11 */
+#define EXTI_RTSR_TR12_Pos (12U)
+#define EXTI_RTSR_TR12_Msk (0x1U << EXTI_RTSR_TR12_Pos) /*!< 0x00001000 */
+#define EXTI_RTSR_TR12 EXTI_RTSR_TR12_Msk /*!< Rising trigger event configuration bit of line 12 */
+#define EXTI_RTSR_TR13_Pos (13U)
+#define EXTI_RTSR_TR13_Msk (0x1U << EXTI_RTSR_TR13_Pos) /*!< 0x00002000 */
+#define EXTI_RTSR_TR13 EXTI_RTSR_TR13_Msk /*!< Rising trigger event configuration bit of line 13 */
+#define EXTI_RTSR_TR14_Pos (14U)
+#define EXTI_RTSR_TR14_Msk (0x1U << EXTI_RTSR_TR14_Pos) /*!< 0x00004000 */
+#define EXTI_RTSR_TR14 EXTI_RTSR_TR14_Msk /*!< Rising trigger event configuration bit of line 14 */
+#define EXTI_RTSR_TR15_Pos (15U)
+#define EXTI_RTSR_TR15_Msk (0x1U << EXTI_RTSR_TR15_Pos) /*!< 0x00008000 */
+#define EXTI_RTSR_TR15 EXTI_RTSR_TR15_Msk /*!< Rising trigger event configuration bit of line 15 */
+#define EXTI_RTSR_TR16_Pos (16U)
+#define EXTI_RTSR_TR16_Msk (0x1U << EXTI_RTSR_TR16_Pos) /*!< 0x00010000 */
+#define EXTI_RTSR_TR16 EXTI_RTSR_TR16_Msk /*!< Rising trigger event configuration bit of line 16 */
+#define EXTI_RTSR_TR17_Pos (17U)
+#define EXTI_RTSR_TR17_Msk (0x1U << EXTI_RTSR_TR17_Pos) /*!< 0x00020000 */
+#define EXTI_RTSR_TR17 EXTI_RTSR_TR17_Msk /*!< Rising trigger event configuration bit of line 17 */
+#define EXTI_RTSR_TR19_Pos (19U)
+#define EXTI_RTSR_TR19_Msk (0x1U << EXTI_RTSR_TR19_Pos) /*!< 0x00080000 */
+#define EXTI_RTSR_TR19 EXTI_RTSR_TR19_Msk /*!< Rising trigger event configuration bit of line 19 */
+
+/* References Defines */
+#define EXTI_RTSR_RT0 EXTI_RTSR_TR0
+#define EXTI_RTSR_RT1 EXTI_RTSR_TR1
+#define EXTI_RTSR_RT2 EXTI_RTSR_TR2
+#define EXTI_RTSR_RT3 EXTI_RTSR_TR3
+#define EXTI_RTSR_RT4 EXTI_RTSR_TR4
+#define EXTI_RTSR_RT5 EXTI_RTSR_TR5
+#define EXTI_RTSR_RT6 EXTI_RTSR_TR6
+#define EXTI_RTSR_RT7 EXTI_RTSR_TR7
+#define EXTI_RTSR_RT8 EXTI_RTSR_TR8
+#define EXTI_RTSR_RT9 EXTI_RTSR_TR9
+#define EXTI_RTSR_RT10 EXTI_RTSR_TR10
+#define EXTI_RTSR_RT11 EXTI_RTSR_TR11
+#define EXTI_RTSR_RT12 EXTI_RTSR_TR12
+#define EXTI_RTSR_RT13 EXTI_RTSR_TR13
+#define EXTI_RTSR_RT14 EXTI_RTSR_TR14
+#define EXTI_RTSR_RT15 EXTI_RTSR_TR15
+#define EXTI_RTSR_RT16 EXTI_RTSR_TR16
+#define EXTI_RTSR_RT17 EXTI_RTSR_TR17
+#define EXTI_RTSR_RT19 EXTI_RTSR_TR19
+
+/******************* Bit definition for EXTI_FTSR register *******************/
+#define EXTI_FTSR_TR0_Pos (0U)
+#define EXTI_FTSR_TR0_Msk (0x1U << EXTI_FTSR_TR0_Pos) /*!< 0x00000001 */
+#define EXTI_FTSR_TR0 EXTI_FTSR_TR0_Msk /*!< Falling trigger event configuration bit of line 0 */
+#define EXTI_FTSR_TR1_Pos (1U)
+#define EXTI_FTSR_TR1_Msk (0x1U << EXTI_FTSR_TR1_Pos) /*!< 0x00000002 */
+#define EXTI_FTSR_TR1 EXTI_FTSR_TR1_Msk /*!< Falling trigger event configuration bit of line 1 */
+#define EXTI_FTSR_TR2_Pos (2U)
+#define EXTI_FTSR_TR2_Msk (0x1U << EXTI_FTSR_TR2_Pos) /*!< 0x00000004 */
+#define EXTI_FTSR_TR2 EXTI_FTSR_TR2_Msk /*!< Falling trigger event configuration bit of line 2 */
+#define EXTI_FTSR_TR3_Pos (3U)
+#define EXTI_FTSR_TR3_Msk (0x1U << EXTI_FTSR_TR3_Pos) /*!< 0x00000008 */
+#define EXTI_FTSR_TR3 EXTI_FTSR_TR3_Msk /*!< Falling trigger event configuration bit of line 3 */
+#define EXTI_FTSR_TR4_Pos (4U)
+#define EXTI_FTSR_TR4_Msk (0x1U << EXTI_FTSR_TR4_Pos) /*!< 0x00000010 */
+#define EXTI_FTSR_TR4 EXTI_FTSR_TR4_Msk /*!< Falling trigger event configuration bit of line 4 */
+#define EXTI_FTSR_TR5_Pos (5U)
+#define EXTI_FTSR_TR5_Msk (0x1U << EXTI_FTSR_TR5_Pos) /*!< 0x00000020 */
+#define EXTI_FTSR_TR5 EXTI_FTSR_TR5_Msk /*!< Falling trigger event configuration bit of line 5 */
+#define EXTI_FTSR_TR6_Pos (6U)
+#define EXTI_FTSR_TR6_Msk (0x1U << EXTI_FTSR_TR6_Pos) /*!< 0x00000040 */
+#define EXTI_FTSR_TR6 EXTI_FTSR_TR6_Msk /*!< Falling trigger event configuration bit of line 6 */
+#define EXTI_FTSR_TR7_Pos (7U)
+#define EXTI_FTSR_TR7_Msk (0x1U << EXTI_FTSR_TR7_Pos) /*!< 0x00000080 */
+#define EXTI_FTSR_TR7 EXTI_FTSR_TR7_Msk /*!< Falling trigger event configuration bit of line 7 */
+#define EXTI_FTSR_TR8_Pos (8U)
+#define EXTI_FTSR_TR8_Msk (0x1U << EXTI_FTSR_TR8_Pos) /*!< 0x00000100 */
+#define EXTI_FTSR_TR8 EXTI_FTSR_TR8_Msk /*!< Falling trigger event configuration bit of line 8 */
+#define EXTI_FTSR_TR9_Pos (9U)
+#define EXTI_FTSR_TR9_Msk (0x1U << EXTI_FTSR_TR9_Pos) /*!< 0x00000200 */
+#define EXTI_FTSR_TR9 EXTI_FTSR_TR9_Msk /*!< Falling trigger event configuration bit of line 9 */
+#define EXTI_FTSR_TR10_Pos (10U)
+#define EXTI_FTSR_TR10_Msk (0x1U << EXTI_FTSR_TR10_Pos) /*!< 0x00000400 */
+#define EXTI_FTSR_TR10 EXTI_FTSR_TR10_Msk /*!< Falling trigger event configuration bit of line 10 */
+#define EXTI_FTSR_TR11_Pos (11U)
+#define EXTI_FTSR_TR11_Msk (0x1U << EXTI_FTSR_TR11_Pos) /*!< 0x00000800 */
+#define EXTI_FTSR_TR11 EXTI_FTSR_TR11_Msk /*!< Falling trigger event configuration bit of line 11 */
+#define EXTI_FTSR_TR12_Pos (12U)
+#define EXTI_FTSR_TR12_Msk (0x1U << EXTI_FTSR_TR12_Pos) /*!< 0x00001000 */
+#define EXTI_FTSR_TR12 EXTI_FTSR_TR12_Msk /*!< Falling trigger event configuration bit of line 12 */
+#define EXTI_FTSR_TR13_Pos (13U)
+#define EXTI_FTSR_TR13_Msk (0x1U << EXTI_FTSR_TR13_Pos) /*!< 0x00002000 */
+#define EXTI_FTSR_TR13 EXTI_FTSR_TR13_Msk /*!< Falling trigger event configuration bit of line 13 */
+#define EXTI_FTSR_TR14_Pos (14U)
+#define EXTI_FTSR_TR14_Msk (0x1U << EXTI_FTSR_TR14_Pos) /*!< 0x00004000 */
+#define EXTI_FTSR_TR14 EXTI_FTSR_TR14_Msk /*!< Falling trigger event configuration bit of line 14 */
+#define EXTI_FTSR_TR15_Pos (15U)
+#define EXTI_FTSR_TR15_Msk (0x1U << EXTI_FTSR_TR15_Pos) /*!< 0x00008000 */
+#define EXTI_FTSR_TR15 EXTI_FTSR_TR15_Msk /*!< Falling trigger event configuration bit of line 15 */
+#define EXTI_FTSR_TR16_Pos (16U)
+#define EXTI_FTSR_TR16_Msk (0x1U << EXTI_FTSR_TR16_Pos) /*!< 0x00010000 */
+#define EXTI_FTSR_TR16 EXTI_FTSR_TR16_Msk /*!< Falling trigger event configuration bit of line 16 */
+#define EXTI_FTSR_TR17_Pos (17U)
+#define EXTI_FTSR_TR17_Msk (0x1U << EXTI_FTSR_TR17_Pos) /*!< 0x00020000 */
+#define EXTI_FTSR_TR17 EXTI_FTSR_TR17_Msk /*!< Falling trigger event configuration bit of line 17 */
+#define EXTI_FTSR_TR19_Pos (19U)
+#define EXTI_FTSR_TR19_Msk (0x1U << EXTI_FTSR_TR19_Pos) /*!< 0x00080000 */
+#define EXTI_FTSR_TR19 EXTI_FTSR_TR19_Msk /*!< Falling trigger event configuration bit of line 19 */
+
+/* References Defines */
+#define EXTI_FTSR_FT0 EXTI_FTSR_TR0
+#define EXTI_FTSR_FT1 EXTI_FTSR_TR1
+#define EXTI_FTSR_FT2 EXTI_FTSR_TR2
+#define EXTI_FTSR_FT3 EXTI_FTSR_TR3
+#define EXTI_FTSR_FT4 EXTI_FTSR_TR4
+#define EXTI_FTSR_FT5 EXTI_FTSR_TR5
+#define EXTI_FTSR_FT6 EXTI_FTSR_TR6
+#define EXTI_FTSR_FT7 EXTI_FTSR_TR7
+#define EXTI_FTSR_FT8 EXTI_FTSR_TR8
+#define EXTI_FTSR_FT9 EXTI_FTSR_TR9
+#define EXTI_FTSR_FT10 EXTI_FTSR_TR10
+#define EXTI_FTSR_FT11 EXTI_FTSR_TR11
+#define EXTI_FTSR_FT12 EXTI_FTSR_TR12
+#define EXTI_FTSR_FT13 EXTI_FTSR_TR13
+#define EXTI_FTSR_FT14 EXTI_FTSR_TR14
+#define EXTI_FTSR_FT15 EXTI_FTSR_TR15
+#define EXTI_FTSR_FT16 EXTI_FTSR_TR16
+#define EXTI_FTSR_FT17 EXTI_FTSR_TR17
+#define EXTI_FTSR_FT19 EXTI_FTSR_TR19
+
+/******************* Bit definition for EXTI_SWIER register *******************/
+#define EXTI_SWIER_SWIER0_Pos (0U)
+#define EXTI_SWIER_SWIER0_Msk (0x1U << EXTI_SWIER_SWIER0_Pos) /*!< 0x00000001 */
+#define EXTI_SWIER_SWIER0 EXTI_SWIER_SWIER0_Msk /*!< Software Interrupt on line 0 */
+#define EXTI_SWIER_SWIER1_Pos (1U)
+#define EXTI_SWIER_SWIER1_Msk (0x1U << EXTI_SWIER_SWIER1_Pos) /*!< 0x00000002 */
+#define EXTI_SWIER_SWIER1 EXTI_SWIER_SWIER1_Msk /*!< Software Interrupt on line 1 */
+#define EXTI_SWIER_SWIER2_Pos (2U)
+#define EXTI_SWIER_SWIER2_Msk (0x1U << EXTI_SWIER_SWIER2_Pos) /*!< 0x00000004 */
+#define EXTI_SWIER_SWIER2 EXTI_SWIER_SWIER2_Msk /*!< Software Interrupt on line 2 */
+#define EXTI_SWIER_SWIER3_Pos (3U)
+#define EXTI_SWIER_SWIER3_Msk (0x1U << EXTI_SWIER_SWIER3_Pos) /*!< 0x00000008 */
+#define EXTI_SWIER_SWIER3 EXTI_SWIER_SWIER3_Msk /*!< Software Interrupt on line 3 */
+#define EXTI_SWIER_SWIER4_Pos (4U)
+#define EXTI_SWIER_SWIER4_Msk (0x1U << EXTI_SWIER_SWIER4_Pos) /*!< 0x00000010 */
+#define EXTI_SWIER_SWIER4 EXTI_SWIER_SWIER4_Msk /*!< Software Interrupt on line 4 */
+#define EXTI_SWIER_SWIER5_Pos (5U)
+#define EXTI_SWIER_SWIER5_Msk (0x1U << EXTI_SWIER_SWIER5_Pos) /*!< 0x00000020 */
+#define EXTI_SWIER_SWIER5 EXTI_SWIER_SWIER5_Msk /*!< Software Interrupt on line 5 */
+#define EXTI_SWIER_SWIER6_Pos (6U)
+#define EXTI_SWIER_SWIER6_Msk (0x1U << EXTI_SWIER_SWIER6_Pos) /*!< 0x00000040 */
+#define EXTI_SWIER_SWIER6 EXTI_SWIER_SWIER6_Msk /*!< Software Interrupt on line 6 */
+#define EXTI_SWIER_SWIER7_Pos (7U)
+#define EXTI_SWIER_SWIER7_Msk (0x1U << EXTI_SWIER_SWIER7_Pos) /*!< 0x00000080 */
+#define EXTI_SWIER_SWIER7 EXTI_SWIER_SWIER7_Msk /*!< Software Interrupt on line 7 */
+#define EXTI_SWIER_SWIER8_Pos (8U)
+#define EXTI_SWIER_SWIER8_Msk (0x1U << EXTI_SWIER_SWIER8_Pos) /*!< 0x00000100 */
+#define EXTI_SWIER_SWIER8 EXTI_SWIER_SWIER8_Msk /*!< Software Interrupt on line 8 */
+#define EXTI_SWIER_SWIER9_Pos (9U)
+#define EXTI_SWIER_SWIER9_Msk (0x1U << EXTI_SWIER_SWIER9_Pos) /*!< 0x00000200 */
+#define EXTI_SWIER_SWIER9 EXTI_SWIER_SWIER9_Msk /*!< Software Interrupt on line 9 */
+#define EXTI_SWIER_SWIER10_Pos (10U)
+#define EXTI_SWIER_SWIER10_Msk (0x1U << EXTI_SWIER_SWIER10_Pos) /*!< 0x00000400 */
+#define EXTI_SWIER_SWIER10 EXTI_SWIER_SWIER10_Msk /*!< Software Interrupt on line 10 */
+#define EXTI_SWIER_SWIER11_Pos (11U)
+#define EXTI_SWIER_SWIER11_Msk (0x1U << EXTI_SWIER_SWIER11_Pos) /*!< 0x00000800 */
+#define EXTI_SWIER_SWIER11 EXTI_SWIER_SWIER11_Msk /*!< Software Interrupt on line 11 */
+#define EXTI_SWIER_SWIER12_Pos (12U)
+#define EXTI_SWIER_SWIER12_Msk (0x1U << EXTI_SWIER_SWIER12_Pos) /*!< 0x00001000 */
+#define EXTI_SWIER_SWIER12 EXTI_SWIER_SWIER12_Msk /*!< Software Interrupt on line 12 */
+#define EXTI_SWIER_SWIER13_Pos (13U)
+#define EXTI_SWIER_SWIER13_Msk (0x1U << EXTI_SWIER_SWIER13_Pos) /*!< 0x00002000 */
+#define EXTI_SWIER_SWIER13 EXTI_SWIER_SWIER13_Msk /*!< Software Interrupt on line 13 */
+#define EXTI_SWIER_SWIER14_Pos (14U)
+#define EXTI_SWIER_SWIER14_Msk (0x1U << EXTI_SWIER_SWIER14_Pos) /*!< 0x00004000 */
+#define EXTI_SWIER_SWIER14 EXTI_SWIER_SWIER14_Msk /*!< Software Interrupt on line 14 */
+#define EXTI_SWIER_SWIER15_Pos (15U)
+#define EXTI_SWIER_SWIER15_Msk (0x1U << EXTI_SWIER_SWIER15_Pos) /*!< 0x00008000 */
+#define EXTI_SWIER_SWIER15 EXTI_SWIER_SWIER15_Msk /*!< Software Interrupt on line 15 */
+#define EXTI_SWIER_SWIER16_Pos (16U)
+#define EXTI_SWIER_SWIER16_Msk (0x1U << EXTI_SWIER_SWIER16_Pos) /*!< 0x00010000 */
+#define EXTI_SWIER_SWIER16 EXTI_SWIER_SWIER16_Msk /*!< Software Interrupt on line 16 */
+#define EXTI_SWIER_SWIER17_Pos (17U)
+#define EXTI_SWIER_SWIER17_Msk (0x1U << EXTI_SWIER_SWIER17_Pos) /*!< 0x00020000 */
+#define EXTI_SWIER_SWIER17 EXTI_SWIER_SWIER17_Msk /*!< Software Interrupt on line 17 */
+#define EXTI_SWIER_SWIER19_Pos (19U)
+#define EXTI_SWIER_SWIER19_Msk (0x1U << EXTI_SWIER_SWIER19_Pos) /*!< 0x00080000 */
+#define EXTI_SWIER_SWIER19 EXTI_SWIER_SWIER19_Msk /*!< Software Interrupt on line 19 */
+
+/* References Defines */
+#define EXTI_SWIER_SWI0 EXTI_SWIER_SWIER0
+#define EXTI_SWIER_SWI1 EXTI_SWIER_SWIER1
+#define EXTI_SWIER_SWI2 EXTI_SWIER_SWIER2
+#define EXTI_SWIER_SWI3 EXTI_SWIER_SWIER3
+#define EXTI_SWIER_SWI4 EXTI_SWIER_SWIER4
+#define EXTI_SWIER_SWI5 EXTI_SWIER_SWIER5
+#define EXTI_SWIER_SWI6 EXTI_SWIER_SWIER6
+#define EXTI_SWIER_SWI7 EXTI_SWIER_SWIER7
+#define EXTI_SWIER_SWI8 EXTI_SWIER_SWIER8
+#define EXTI_SWIER_SWI9 EXTI_SWIER_SWIER9
+#define EXTI_SWIER_SWI10 EXTI_SWIER_SWIER10
+#define EXTI_SWIER_SWI11 EXTI_SWIER_SWIER11
+#define EXTI_SWIER_SWI12 EXTI_SWIER_SWIER12
+#define EXTI_SWIER_SWI13 EXTI_SWIER_SWIER13
+#define EXTI_SWIER_SWI14 EXTI_SWIER_SWIER14
+#define EXTI_SWIER_SWI15 EXTI_SWIER_SWIER15
+#define EXTI_SWIER_SWI16 EXTI_SWIER_SWIER16
+#define EXTI_SWIER_SWI17 EXTI_SWIER_SWIER17
+#define EXTI_SWIER_SWI19 EXTI_SWIER_SWIER19
+
+/****************** Bit definition for EXTI_PR register *********************/
+#define EXTI_PR_PR0_Pos (0U)
+#define EXTI_PR_PR0_Msk (0x1U << EXTI_PR_PR0_Pos) /*!< 0x00000001 */
+#define EXTI_PR_PR0 EXTI_PR_PR0_Msk /*!< Pending bit 0 */
+#define EXTI_PR_PR1_Pos (1U)
+#define EXTI_PR_PR1_Msk (0x1U << EXTI_PR_PR1_Pos) /*!< 0x00000002 */
+#define EXTI_PR_PR1 EXTI_PR_PR1_Msk /*!< Pending bit 1 */
+#define EXTI_PR_PR2_Pos (2U)
+#define EXTI_PR_PR2_Msk (0x1U << EXTI_PR_PR2_Pos) /*!< 0x00000004 */
+#define EXTI_PR_PR2 EXTI_PR_PR2_Msk /*!< Pending bit 2 */
+#define EXTI_PR_PR3_Pos (3U)
+#define EXTI_PR_PR3_Msk (0x1U << EXTI_PR_PR3_Pos) /*!< 0x00000008 */
+#define EXTI_PR_PR3 EXTI_PR_PR3_Msk /*!< Pending bit 3 */
+#define EXTI_PR_PR4_Pos (4U)
+#define EXTI_PR_PR4_Msk (0x1U << EXTI_PR_PR4_Pos) /*!< 0x00000010 */
+#define EXTI_PR_PR4 EXTI_PR_PR4_Msk /*!< Pending bit 4 */
+#define EXTI_PR_PR5_Pos (5U)
+#define EXTI_PR_PR5_Msk (0x1U << EXTI_PR_PR5_Pos) /*!< 0x00000020 */
+#define EXTI_PR_PR5 EXTI_PR_PR5_Msk /*!< Pending bit 5 */
+#define EXTI_PR_PR6_Pos (6U)
+#define EXTI_PR_PR6_Msk (0x1U << EXTI_PR_PR6_Pos) /*!< 0x00000040 */
+#define EXTI_PR_PR6 EXTI_PR_PR6_Msk /*!< Pending bit 6 */
+#define EXTI_PR_PR7_Pos (7U)
+#define EXTI_PR_PR7_Msk (0x1U << EXTI_PR_PR7_Pos) /*!< 0x00000080 */
+#define EXTI_PR_PR7 EXTI_PR_PR7_Msk /*!< Pending bit 7 */
+#define EXTI_PR_PR8_Pos (8U)
+#define EXTI_PR_PR8_Msk (0x1U << EXTI_PR_PR8_Pos) /*!< 0x00000100 */
+#define EXTI_PR_PR8 EXTI_PR_PR8_Msk /*!< Pending bit 8 */
+#define EXTI_PR_PR9_Pos (9U)
+#define EXTI_PR_PR9_Msk (0x1U << EXTI_PR_PR9_Pos) /*!< 0x00000200 */
+#define EXTI_PR_PR9 EXTI_PR_PR9_Msk /*!< Pending bit 9 */
+#define EXTI_PR_PR10_Pos (10U)
+#define EXTI_PR_PR10_Msk (0x1U << EXTI_PR_PR10_Pos) /*!< 0x00000400 */
+#define EXTI_PR_PR10 EXTI_PR_PR10_Msk /*!< Pending bit 10 */
+#define EXTI_PR_PR11_Pos (11U)
+#define EXTI_PR_PR11_Msk (0x1U << EXTI_PR_PR11_Pos) /*!< 0x00000800 */
+#define EXTI_PR_PR11 EXTI_PR_PR11_Msk /*!< Pending bit 11 */
+#define EXTI_PR_PR12_Pos (12U)
+#define EXTI_PR_PR12_Msk (0x1U << EXTI_PR_PR12_Pos) /*!< 0x00001000 */
+#define EXTI_PR_PR12 EXTI_PR_PR12_Msk /*!< Pending bit 12 */
+#define EXTI_PR_PR13_Pos (13U)
+#define EXTI_PR_PR13_Msk (0x1U << EXTI_PR_PR13_Pos) /*!< 0x00002000 */
+#define EXTI_PR_PR13 EXTI_PR_PR13_Msk /*!< Pending bit 13 */
+#define EXTI_PR_PR14_Pos (14U)
+#define EXTI_PR_PR14_Msk (0x1U << EXTI_PR_PR14_Pos) /*!< 0x00004000 */
+#define EXTI_PR_PR14 EXTI_PR_PR14_Msk /*!< Pending bit 14 */
+#define EXTI_PR_PR15_Pos (15U)
+#define EXTI_PR_PR15_Msk (0x1U << EXTI_PR_PR15_Pos) /*!< 0x00008000 */
+#define EXTI_PR_PR15 EXTI_PR_PR15_Msk /*!< Pending bit 15 */
+#define EXTI_PR_PR16_Pos (16U)
+#define EXTI_PR_PR16_Msk (0x1U << EXTI_PR_PR16_Pos) /*!< 0x00010000 */
+#define EXTI_PR_PR16 EXTI_PR_PR16_Msk /*!< Pending bit 16 */
+#define EXTI_PR_PR17_Pos (17U)
+#define EXTI_PR_PR17_Msk (0x1U << EXTI_PR_PR17_Pos) /*!< 0x00020000 */
+#define EXTI_PR_PR17 EXTI_PR_PR17_Msk /*!< Pending bit 17 */
+#define EXTI_PR_PR19_Pos (19U)
+#define EXTI_PR_PR19_Msk (0x1U << EXTI_PR_PR19_Pos) /*!< 0x00080000 */
+#define EXTI_PR_PR19 EXTI_PR_PR19_Msk /*!< Pending bit 19 */
+
+/* References Defines */
+#define EXTI_PR_PIF0 EXTI_PR_PR0
+#define EXTI_PR_PIF1 EXTI_PR_PR1
+#define EXTI_PR_PIF2 EXTI_PR_PR2
+#define EXTI_PR_PIF3 EXTI_PR_PR3
+#define EXTI_PR_PIF4 EXTI_PR_PR4
+#define EXTI_PR_PIF5 EXTI_PR_PR5
+#define EXTI_PR_PIF6 EXTI_PR_PR6
+#define EXTI_PR_PIF7 EXTI_PR_PR7
+#define EXTI_PR_PIF8 EXTI_PR_PR8
+#define EXTI_PR_PIF9 EXTI_PR_PR9
+#define EXTI_PR_PIF10 EXTI_PR_PR10
+#define EXTI_PR_PIF11 EXTI_PR_PR11
+#define EXTI_PR_PIF12 EXTI_PR_PR12
+#define EXTI_PR_PIF13 EXTI_PR_PR13
+#define EXTI_PR_PIF14 EXTI_PR_PR14
+#define EXTI_PR_PIF15 EXTI_PR_PR15
+#define EXTI_PR_PIF16 EXTI_PR_PR16
+#define EXTI_PR_PIF17 EXTI_PR_PR17
+#define EXTI_PR_PIF19 EXTI_PR_PR19
+
+/******************************************************************************/
+/* */
+/* FLASH and Option Bytes Registers */
+/* */
+/******************************************************************************/
+
+
+
+/******************* Bit definition for FLASH_ACR register ******************/
+#define FLASH_ACR_LATENCY ((uint32_t)0x00000007) /*!< LATENCY bit (Latency) */
+
+
+
+/****************** Bit definition for FLASH_KEYR register ******************/
+#define FLASH_KEYR_FKEYR ((uint32_t)0xFFFFFFFF) /*!< FPEC Key */
+
+/***************** Bit definition for FLASH_OPTKEYR register ****************/
+#define FLASH_OPTKEYR_OPTKEYR ((uint32_t)0xFFFFFFFF) /*!< Option Byte Key */
+
+/****************** FLASH Keys **********************************************/
+#define FLASH_FKEY1 ((uint32_t)0x45670123) /*!< Flash program erase key1 */
+#define FLASH_FKEY2 ((uint32_t)0xCDEF89AB) /*!< Flash program erase key2: used with FLASH_PEKEY1
+ to unlock the write access to the FPEC. */
+
+#define FLASH_OPTKEY1 ((uint32_t)0x45670123) /*!< Flash option key1 */
+#define FLASH_OPTKEY2 ((uint32_t)0xCDEF89AB) /*!< Flash option key2: used with FLASH_OPTKEY1 to
+ unlock the write access to the option byte block */
+
+/****************** Bit definition for FLASH_SR register *******************/
+#define FLASH_SR_BSY ((uint32_t)0x00000001) /*!< Busy */
+#define FLASH_SR_WRPRTERR ((uint32_t)0x00000010) /*!< Write Protection Error */
+#define FLASH_SR_EOP ((uint32_t)0x00000020) /*!< End of operation */
+#define FLASH_SR_WRPERR FLASH_SR_WRPRTERR /*!< Legacy of Write Protection Error */
+
+/******************* Bit definition for FLASH_CR register *******************/
+#define FLASH_CR_PG ((uint32_t)0x00000001) /*!< Programming */
+#define FLASH_CR_PER ((uint32_t)0x00000002) /*!< Page Erase */
+#define FLASH_CR_MER ((uint32_t)0x00000004) /*!< Mass Erase */
+#define FLASH_CR_OPTPG ((uint32_t)0x00000010) /*!< OB half word Programming */
+#define FLASH_CR_OPTER ((uint32_t)0x00000020) /*!< OB byte Erase */
+#define FLASH_CR_STRT ((uint32_t)0x00000040) /*!< Start */
+#define FLASH_CR_LOCK ((uint32_t)0x00000080) /*!< Lock */
+#define FLASH_CR_OPTWRE ((uint32_t)0x00000200) /*!< Option Bytes Write Enable */
+#define FLASH_CR_ERRIE ((uint32_t)0x00000400) /*!< Error Interrupt Enable */
+#define FLASH_CR_EOPIE ((uint32_t)0x00001000) /*!< End of operation interrupt enable */
+
+/******************* Bit definition for FLASH_AR register *******************/
+#define FLASH_AR_FAR ((uint32_t)0xFFFFFFFF) /*!< Flash Address */
+
+/****************** Bit definition for FLASH_OBR register *******************/
+#define FLASH_OBR_OPTERR ((uint32_t)0x00000001) /*!< Option Byte Error */
+#define FLASH_OBR_RDPRT1 ((uint32_t)0x00000002) /*!< Read protection Level bit 1 */
+#define FLASH_OBR_RDPRT2 ((uint32_t)0x00000004) /*!< Read protection Level bit 2 */
+
+#define FLASH_OBR_IWDG_SW ((uint32_t)0x00000100) /*!< IWDG SW */
+#define FLASH_OBR_nRST_STOP ((uint32_t)0x00000200) /*!< nRST_STOP */
+#define FLASH_OBR_VDDA_MONITOR ((uint32_t)0x00002000) /*!< VDDA power supply supervisor */
+#define FLASH_OBR_DATA0 ((uint32_t)0x00FF0000) /*!< DATA0 */
+#define FLASH_OBR_DATA1 ((uint32_t)0xFF000000) /*!< DATA0 */
+
+/* Old OBR_VDDA bit definition, maintained for legacy purpose */
+#define FLASH_OBR_VDDA_ANALOG FLASH_OBR_VDDA_MONITOR
+
+/****************** Bit definition for FLASH_WRPR register ******************/
+#define FLASH_WRPR_WRP ((uint32_t)0xFFFFFFFF) /*!< Write Protect */
+
+/****************** Bit definition for FLASH_ECR register ******************/
+#define FLASH_ECR_BPG ((uint32_t)0x00000001) /*!< byte program */
+#define FLASH_ECR_EEPROM_ER ((uint32_t)0x00000002) /*!< EEPROM byte erase */
+#define FLASH_ECR_EEPROM_BPG ((uint32_t)0x00000004) /*!< EEPROM byte program */
+
+/*----------------------------------------------------------------------------*/
+
+/****************** Bit definition for OB_RDP register **********************/
+#define OB_RDP_RDP_Pos (0U)
+#define OB_RDP_RDP_Msk (0xFFU << OB_RDP_RDP_Pos) /*!< 0x000000FF */
+#define OB_RDP_RDP OB_RDP_RDP_Msk /*!< Read protection option byte */
+#define OB_RDP_nRDP_Pos (8U)
+#define OB_RDP_nRDP_Msk (0xFFU << OB_RDP_nRDP_Pos) /*!< 0x0000FF00 */
+#define OB_RDP_nRDP OB_RDP_nRDP_Msk /*!< Read protection complemented option byte */
+
+/****************** Bit definition for OB_USER register *********************/
+#define OB_USER_USER_Pos (16U)
+#define OB_USER_USER_Msk (0xFFU << OB_USER_USER_Pos) /*!< 0x00FF0000 */
+#define OB_USER_USER OB_USER_USER_Msk /*!< User option byte */
+#define OB_USER_nUSER_Pos (24U)
+#define OB_USER_nUSER_Msk (0xFFU << OB_USER_nUSER_Pos) /*!< 0xFF000000 */
+#define OB_USER_nUSER OB_USER_nUSER_Msk /*!< User complemented option byte */
+
+/****************** Bit definition for OB_WRP0 register *********************/
+#define OB_WRP0_WRP0_Pos (0U)
+#define OB_WRP0_WRP0_Msk (0xFFU << OB_WRP0_WRP0_Pos) /*!< 0x000000FF */
+#define OB_WRP0_WRP0 OB_WRP0_WRP0_Msk /*!< Flash memory write protection option bytes */
+#define OB_WRP0_nWRP0_Pos (8U)
+#define OB_WRP0_nWRP0_Msk (0xFFU << OB_WRP0_nWRP0_Pos) /*!< 0x0000FF00 */
+#define OB_WRP0_nWRP0 OB_WRP0_nWRP0_Msk /*!< Flash memory write protection complemented option bytes */
+
+/****************** Bit definition for OB_WRP1 register *********************/
+#define OB_WRP1_WRP1_Pos (16U)
+#define OB_WRP1_WRP1_Msk (0xFFU << OB_WRP1_WRP1_Pos) /*!< 0x00FF0000 */
+#define OB_WRP1_WRP1 OB_WRP1_WRP1_Msk /*!< Flash memory write protection option bytes */
+#define OB_WRP1_nWRP1_Pos (24U)
+#define OB_WRP1_nWRP1_Msk (0xFFU << OB_WRP1_nWRP1_Pos) /*!< 0xFF000000 */
+#define OB_WRP1_nWRP1 OB_WRP1_nWRP1_Msk /*!< Flash memory write protection complemented option bytes */
+
+/******************************************************************************/
+/* */
+/* General Purpose IOs (GPIO) */
+/* */
+/******************************************************************************/
+/******************* Bit definition for GPIO_MODER register *****************/
+#define GPIO_MODER_MODER0_Pos (0U)
+#define GPIO_MODER_MODER0_Msk (0x3U << GPIO_MODER_MODER0_Pos) /*!< 0x00000003 */
+#define GPIO_MODER_MODER0 GPIO_MODER_MODER0_Msk
+#define GPIO_MODER_MODER0_0 (0x1U << GPIO_MODER_MODER0_Pos) /*!< 0x00000001 */
+#define GPIO_MODER_MODER0_1 (0x2U << GPIO_MODER_MODER0_Pos) /*!< 0x00000002 */
+#define GPIO_MODER_MODER1_Pos (2U)
+#define GPIO_MODER_MODER1_Msk (0x3U << GPIO_MODER_MODER1_Pos) /*!< 0x0000000C */
+#define GPIO_MODER_MODER1 GPIO_MODER_MODER1_Msk
+#define GPIO_MODER_MODER1_0 (0x1U << GPIO_MODER_MODER1_Pos) /*!< 0x00000004 */
+#define GPIO_MODER_MODER1_1 (0x2U << GPIO_MODER_MODER1_Pos) /*!< 0x00000008 */
+#define GPIO_MODER_MODER2_Pos (4U)
+#define GPIO_MODER_MODER2_Msk (0x3U << GPIO_MODER_MODER2_Pos) /*!< 0x00000030 */
+#define GPIO_MODER_MODER2 GPIO_MODER_MODER2_Msk
+#define GPIO_MODER_MODER2_0 (0x1U << GPIO_MODER_MODER2_Pos) /*!< 0x00000010 */
+#define GPIO_MODER_MODER2_1 (0x2U << GPIO_MODER_MODER2_Pos) /*!< 0x00000020 */
+#define GPIO_MODER_MODER3_Pos (6U)
+#define GPIO_MODER_MODER3_Msk (0x3U << GPIO_MODER_MODER3_Pos) /*!< 0x000000C0 */
+#define GPIO_MODER_MODER3 GPIO_MODER_MODER3_Msk
+#define GPIO_MODER_MODER3_0 (0x1U << GPIO_MODER_MODER3_Pos) /*!< 0x00000040 */
+#define GPIO_MODER_MODER3_1 (0x2U << GPIO_MODER_MODER3_Pos) /*!< 0x00000080 */
+#define GPIO_MODER_MODER4_Pos (8U)
+#define GPIO_MODER_MODER4_Msk (0x3U << GPIO_MODER_MODER4_Pos) /*!< 0x00000300 */
+#define GPIO_MODER_MODER4 GPIO_MODER_MODER4_Msk
+#define GPIO_MODER_MODER4_0 (0x1U << GPIO_MODER_MODER4_Pos) /*!< 0x00000100 */
+#define GPIO_MODER_MODER4_1 (0x2U << GPIO_MODER_MODER4_Pos) /*!< 0x00000200 */
+#define GPIO_MODER_MODER5_Pos (10U)
+#define GPIO_MODER_MODER5_Msk (0x3U << GPIO_MODER_MODER5_Pos) /*!< 0x00000C00 */
+#define GPIO_MODER_MODER5 GPIO_MODER_MODER5_Msk
+#define GPIO_MODER_MODER5_0 (0x1U << GPIO_MODER_MODER5_Pos) /*!< 0x00000400 */
+#define GPIO_MODER_MODER5_1 (0x2U << GPIO_MODER_MODER5_Pos) /*!< 0x00000800 */
+#define GPIO_MODER_MODER6_Pos (12U)
+#define GPIO_MODER_MODER6_Msk (0x3U << GPIO_MODER_MODER6_Pos) /*!< 0x00003000 */
+#define GPIO_MODER_MODER6 GPIO_MODER_MODER6_Msk
+#define GPIO_MODER_MODER6_0 (0x1U << GPIO_MODER_MODER6_Pos) /*!< 0x00001000 */
+#define GPIO_MODER_MODER6_1 (0x2U << GPIO_MODER_MODER6_Pos) /*!< 0x00002000 */
+#define GPIO_MODER_MODER7_Pos (14U)
+#define GPIO_MODER_MODER7_Msk (0x3U << GPIO_MODER_MODER7_Pos) /*!< 0x0000C000 */
+#define GPIO_MODER_MODER7 GPIO_MODER_MODER7_Msk
+#define GPIO_MODER_MODER7_0 (0x1U << GPIO_MODER_MODER7_Pos) /*!< 0x00004000 */
+#define GPIO_MODER_MODER7_1 (0x2U << GPIO_MODER_MODER7_Pos) /*!< 0x00008000 */
+#define GPIO_MODER_MODER8_Pos (16U)
+#define GPIO_MODER_MODER8_Msk (0x3U << GPIO_MODER_MODER8_Pos) /*!< 0x00030000 */
+#define GPIO_MODER_MODER8 GPIO_MODER_MODER8_Msk
+#define GPIO_MODER_MODER8_0 (0x1U << GPIO_MODER_MODER8_Pos) /*!< 0x00010000 */
+#define GPIO_MODER_MODER8_1 (0x2U << GPIO_MODER_MODER8_Pos) /*!< 0x00020000 */
+#define GPIO_MODER_MODER9_Pos (18U)
+#define GPIO_MODER_MODER9_Msk (0x3U << GPIO_MODER_MODER9_Pos) /*!< 0x000C0000 */
+#define GPIO_MODER_MODER9 GPIO_MODER_MODER9_Msk
+#define GPIO_MODER_MODER9_0 (0x1U << GPIO_MODER_MODER9_Pos) /*!< 0x00040000 */
+#define GPIO_MODER_MODER9_1 (0x2U << GPIO_MODER_MODER9_Pos) /*!< 0x00080000 */
+#define GPIO_MODER_MODER10_Pos (20U)
+#define GPIO_MODER_MODER10_Msk (0x3U << GPIO_MODER_MODER10_Pos) /*!< 0x00300000 */
+#define GPIO_MODER_MODER10 GPIO_MODER_MODER10_Msk
+#define GPIO_MODER_MODER10_0 (0x1U << GPIO_MODER_MODER10_Pos) /*!< 0x00100000 */
+#define GPIO_MODER_MODER10_1 (0x2U << GPIO_MODER_MODER10_Pos) /*!< 0x00200000 */
+#define GPIO_MODER_MODER11_Pos (22U)
+#define GPIO_MODER_MODER11_Msk (0x3U << GPIO_MODER_MODER11_Pos) /*!< 0x00C00000 */
+#define GPIO_MODER_MODER11 GPIO_MODER_MODER11_Msk
+#define GPIO_MODER_MODER11_0 (0x1U << GPIO_MODER_MODER11_Pos) /*!< 0x00400000 */
+#define GPIO_MODER_MODER11_1 (0x2U << GPIO_MODER_MODER11_Pos) /*!< 0x00800000 */
+#define GPIO_MODER_MODER12_Pos (24U)
+#define GPIO_MODER_MODER12_Msk (0x3U << GPIO_MODER_MODER12_Pos) /*!< 0x03000000 */
+#define GPIO_MODER_MODER12 GPIO_MODER_MODER12_Msk
+#define GPIO_MODER_MODER12_0 (0x1U << GPIO_MODER_MODER12_Pos) /*!< 0x01000000 */
+#define GPIO_MODER_MODER12_1 (0x2U << GPIO_MODER_MODER12_Pos) /*!< 0x02000000 */
+#define GPIO_MODER_MODER13_Pos (26U)
+#define GPIO_MODER_MODER13_Msk (0x3U << GPIO_MODER_MODER13_Pos) /*!< 0x0C000000 */
+#define GPIO_MODER_MODER13 GPIO_MODER_MODER13_Msk
+#define GPIO_MODER_MODER13_0 (0x1U << GPIO_MODER_MODER13_Pos) /*!< 0x04000000 */
+#define GPIO_MODER_MODER13_1 (0x2U << GPIO_MODER_MODER13_Pos) /*!< 0x08000000 */
+#define GPIO_MODER_MODER14_Pos (28U)
+#define GPIO_MODER_MODER14_Msk (0x3U << GPIO_MODER_MODER14_Pos) /*!< 0x30000000 */
+#define GPIO_MODER_MODER14 GPIO_MODER_MODER14_Msk
+#define GPIO_MODER_MODER14_0 (0x1U << GPIO_MODER_MODER14_Pos) /*!< 0x10000000 */
+#define GPIO_MODER_MODER14_1 (0x2U << GPIO_MODER_MODER14_Pos) /*!< 0x20000000 */
+#define GPIO_MODER_MODER15_Pos (30U)
+#define GPIO_MODER_MODER15_Msk (0x3U << GPIO_MODER_MODER15_Pos) /*!< 0xC0000000 */
+#define GPIO_MODER_MODER15 GPIO_MODER_MODER15_Msk
+#define GPIO_MODER_MODER15_0 (0x1U << GPIO_MODER_MODER15_Pos) /*!< 0x40000000 */
+#define GPIO_MODER_MODER15_1 (0x2U << GPIO_MODER_MODER15_Pos) /*!< 0x80000000 */
+
+/****************** Bit definition for GPIO_OTYPER register *****************/
+#define GPIO_OTYPER_OT_0 (0x00000001U)
+#define GPIO_OTYPER_OT_1 (0x00000002U)
+#define GPIO_OTYPER_OT_2 (0x00000004U)
+#define GPIO_OTYPER_OT_3 (0x00000008U)
+#define GPIO_OTYPER_OT_4 (0x00000010U)
+#define GPIO_OTYPER_OT_5 (0x00000020U)
+#define GPIO_OTYPER_OT_6 (0x00000040U)
+#define GPIO_OTYPER_OT_7 (0x00000080U)
+#define GPIO_OTYPER_OT_8 (0x00000100U)
+#define GPIO_OTYPER_OT_9 (0x00000200U)
+#define GPIO_OTYPER_OT_10 (0x00000400U)
+#define GPIO_OTYPER_OT_11 (0x00000800U)
+#define GPIO_OTYPER_OT_12 (0x00001000U)
+#define GPIO_OTYPER_OT_13 (0x00002000U)
+#define GPIO_OTYPER_OT_14 (0x00004000U)
+#define GPIO_OTYPER_OT_15 (0x00008000U)
+
+/**************** Bit definition for GPIO_OSPEEDR register ******************/
+#define GPIO_OSPEEDR_OSPEEDR0_Pos (0U)
+#define GPIO_OSPEEDR_OSPEEDR0_Msk (0x3U << GPIO_OSPEEDR_OSPEEDR0_Pos) /*!< 0x00000003 */
+#define GPIO_OSPEEDR_OSPEEDR0 GPIO_OSPEEDR_OSPEEDR0_Msk
+#define GPIO_OSPEEDR_OSPEEDR0_0 (0x1U << GPIO_OSPEEDR_OSPEEDR0_Pos) /*!< 0x00000001 */
+
+#define GPIO_OSPEEDR_OSPEEDR1_Pos (2U)
+#define GPIO_OSPEEDR_OSPEEDR1_Msk (0x3U << GPIO_OSPEEDR_OSPEEDR1_Pos) /*!< 0x0000000C */
+#define GPIO_OSPEEDR_OSPEEDR1 GPIO_OSPEEDR_OSPEEDR1_Msk
+#define GPIO_OSPEEDR_OSPEEDR1_0 (0x1U << GPIO_OSPEEDR_OSPEEDR1_Pos) /*!< 0x00000004 */
+
+#define GPIO_OSPEEDR_OSPEEDR2_Pos (4U)
+#define GPIO_OSPEEDR_OSPEEDR2_Msk (0x3U << GPIO_OSPEEDR_OSPEEDR2_Pos) /*!< 0x00000030 */
+#define GPIO_OSPEEDR_OSPEEDR2 GPIO_OSPEEDR_OSPEEDR2_Msk
+#define GPIO_OSPEEDR_OSPEEDR2_0 (0x1U << GPIO_OSPEEDR_OSPEEDR2_Pos) /*!< 0x00000010 */
+
+#define GPIO_OSPEEDR_OSPEEDR3_Pos (6U)
+#define GPIO_OSPEEDR_OSPEEDR3_Msk (0x3U << GPIO_OSPEEDR_OSPEEDR3_Pos) /*!< 0x000000C0 */
+#define GPIO_OSPEEDR_OSPEEDR3 GPIO_OSPEEDR_OSPEEDR3_Msk
+#define GPIO_OSPEEDR_OSPEEDR3_0 (0x1U << GPIO_OSPEEDR_OSPEEDR3_Pos) /*!< 0x00000040 */
+
+#define GPIO_OSPEEDR_OSPEEDR4_Pos (8U)
+#define GPIO_OSPEEDR_OSPEEDR4_Msk (0x3U << GPIO_OSPEEDR_OSPEEDR4_Pos) /*!< 0x00000300 */
+#define GPIO_OSPEEDR_OSPEEDR4 GPIO_OSPEEDR_OSPEEDR4_Msk
+#define GPIO_OSPEEDR_OSPEEDR4_0 (0x1U << GPIO_OSPEEDR_OSPEEDR4_Pos) /*!< 0x00000100 */
+
+#define GPIO_OSPEEDR_OSPEEDR5_Pos (10U)
+#define GPIO_OSPEEDR_OSPEEDR5_Msk (0x3U << GPIO_OSPEEDR_OSPEEDR5_Pos) /*!< 0x00000C00 */
+#define GPIO_OSPEEDR_OSPEEDR5 GPIO_OSPEEDR_OSPEEDR5_Msk
+#define GPIO_OSPEEDR_OSPEEDR5_0 (0x1U << GPIO_OSPEEDR_OSPEEDR5_Pos) /*!< 0x00000400 */
+
+#define GPIO_OSPEEDR_OSPEEDR6_Pos (12U)
+#define GPIO_OSPEEDR_OSPEEDR6_Msk (0x3U << GPIO_OSPEEDR_OSPEEDR6_Pos) /*!< 0x00003000 */
+#define GPIO_OSPEEDR_OSPEEDR6 GPIO_OSPEEDR_OSPEEDR6_Msk
+#define GPIO_OSPEEDR_OSPEEDR6_0 (0x1U << GPIO_OSPEEDR_OSPEEDR6_Pos) /*!< 0x00001000 */
+
+#define GPIO_OSPEEDR_OSPEEDR7_Pos (14U)
+#define GPIO_OSPEEDR_OSPEEDR7_Msk (0x3U << GPIO_OSPEEDR_OSPEEDR7_Pos) /*!< 0x0000C000 */
+#define GPIO_OSPEEDR_OSPEEDR7 GPIO_OSPEEDR_OSPEEDR7_Msk
+#define GPIO_OSPEEDR_OSPEEDR7_0 (0x1U << GPIO_OSPEEDR_OSPEEDR7_Pos) /*!< 0x00004000 */
+
+#define GPIO_OSPEEDR_OSPEEDR8_Pos (16U)
+#define GPIO_OSPEEDR_OSPEEDR8_Msk (0x3U << GPIO_OSPEEDR_OSPEEDR8_Pos) /*!< 0x00030000 */
+#define GPIO_OSPEEDR_OSPEEDR8 GPIO_OSPEEDR_OSPEEDR8_Msk
+#define GPIO_OSPEEDR_OSPEEDR8_0 (0x1U << GPIO_OSPEEDR_OSPEEDR8_Pos) /*!< 0x00010000 */
+
+#define GPIO_OSPEEDR_OSPEEDR9_Pos (18U)
+#define GPIO_OSPEEDR_OSPEEDR9_Msk (0x3U << GPIO_OSPEEDR_OSPEEDR9_Pos) /*!< 0x000C0000 */
+#define GPIO_OSPEEDR_OSPEEDR9 GPIO_OSPEEDR_OSPEEDR9_Msk
+#define GPIO_OSPEEDR_OSPEEDR9_0 (0x1U << GPIO_OSPEEDR_OSPEEDR9_Pos) /*!< 0x00040000 */
+
+#define GPIO_OSPEEDR_OSPEEDR10_Pos (20U)
+#define GPIO_OSPEEDR_OSPEEDR10_Msk (0x3U << GPIO_OSPEEDR_OSPEEDR10_Pos) /*!< 0x00300000 */
+#define GPIO_OSPEEDR_OSPEEDR10 GPIO_OSPEEDR_OSPEEDR10_Msk
+#define GPIO_OSPEEDR_OSPEEDR10_0 (0x1U << GPIO_OSPEEDR_OSPEEDR10_Pos) /*!< 0x00100000 */
+
+#define GPIO_OSPEEDR_OSPEEDR11_Pos (22U)
+#define GPIO_OSPEEDR_OSPEEDR11_Msk (0x3U << GPIO_OSPEEDR_OSPEEDR11_Pos) /*!< 0x00C00000 */
+#define GPIO_OSPEEDR_OSPEEDR11 GPIO_OSPEEDR_OSPEEDR11_Msk
+#define GPIO_OSPEEDR_OSPEEDR11_0 (0x1U << GPIO_OSPEEDR_OSPEEDR11_Pos) /*!< 0x00400000 */
+
+#define GPIO_OSPEEDR_OSPEEDR12_Pos (24U)
+#define GPIO_OSPEEDR_OSPEEDR12_Msk (0x3U << GPIO_OSPEEDR_OSPEEDR12_Pos) /*!< 0x03000000 */
+#define GPIO_OSPEEDR_OSPEEDR12 GPIO_OSPEEDR_OSPEEDR12_Msk
+#define GPIO_OSPEEDR_OSPEEDR12_0 (0x1U << GPIO_OSPEEDR_OSPEEDR12_Pos) /*!< 0x01000000 */
+
+#define GPIO_OSPEEDR_OSPEEDR13_Pos (26U)
+#define GPIO_OSPEEDR_OSPEEDR13_Msk (0x3U << GPIO_OSPEEDR_OSPEEDR13_Pos) /*!< 0x0C000000 */
+#define GPIO_OSPEEDR_OSPEEDR13 GPIO_OSPEEDR_OSPEEDR13_Msk
+#define GPIO_OSPEEDR_OSPEEDR13_0 (0x1U << GPIO_OSPEEDR_OSPEEDR13_Pos) /*!< 0x04000000 */
+
+#define GPIO_OSPEEDR_OSPEEDR14_Pos (28U)
+#define GPIO_OSPEEDR_OSPEEDR14_Msk (0x3U << GPIO_OSPEEDR_OSPEEDR14_Pos) /*!< 0x30000000 */
+#define GPIO_OSPEEDR_OSPEEDR14 GPIO_OSPEEDR_OSPEEDR14_Msk
+#define GPIO_OSPEEDR_OSPEEDR14_0 (0x1U << GPIO_OSPEEDR_OSPEEDR14_Pos) /*!< 0x10000000 */
+
+#define GPIO_OSPEEDR_OSPEEDR15_Pos (30U)
+#define GPIO_OSPEEDR_OSPEEDR15_Msk (0x3U << GPIO_OSPEEDR_OSPEEDR15_Pos) /*!< 0xC0000000 */
+#define GPIO_OSPEEDR_OSPEEDR15 GPIO_OSPEEDR_OSPEEDR15_Msk
+#define GPIO_OSPEEDR_OSPEEDR15_0 (0x1U << GPIO_OSPEEDR_OSPEEDR15_Pos) /*!< 0x40000000 */
+
+
+/******************* Bit definition for GPIO_PUPDR register ******************/
+#define GPIO_PUPDR_PUPDR0_Pos (0U)
+#define GPIO_PUPDR_PUPDR0_Msk (0x3U << GPIO_PUPDR_PUPDR0_Pos) /*!< 0x00000003 */
+#define GPIO_PUPDR_PUPDR0 GPIO_PUPDR_PUPDR0_Msk
+#define GPIO_PUPDR_PUPDR0_0 (0x1U << GPIO_PUPDR_PUPDR0_Pos) /*!< 0x00000001 */
+#define GPIO_PUPDR_PUPDR0_1 (0x2U << GPIO_PUPDR_PUPDR0_Pos) /*!< 0x00000002 */
+#define GPIO_PUPDR_PUPDR1_Pos (2U)
+#define GPIO_PUPDR_PUPDR1_Msk (0x3U << GPIO_PUPDR_PUPDR1_Pos) /*!< 0x0000000C */
+#define GPIO_PUPDR_PUPDR1 GPIO_PUPDR_PUPDR1_Msk
+#define GPIO_PUPDR_PUPDR1_0 (0x1U << GPIO_PUPDR_PUPDR1_Pos) /*!< 0x00000004 */
+#define GPIO_PUPDR_PUPDR1_1 (0x2U << GPIO_PUPDR_PUPDR1_Pos) /*!< 0x00000008 */
+#define GPIO_PUPDR_PUPDR2_Pos (4U)
+#define GPIO_PUPDR_PUPDR2_Msk (0x3U << GPIO_PUPDR_PUPDR2_Pos) /*!< 0x00000030 */
+#define GPIO_PUPDR_PUPDR2 GPIO_PUPDR_PUPDR2_Msk
+#define GPIO_PUPDR_PUPDR2_0 (0x1U << GPIO_PUPDR_PUPDR2_Pos) /*!< 0x00000010 */
+#define GPIO_PUPDR_PUPDR2_1 (0x2U << GPIO_PUPDR_PUPDR2_Pos) /*!< 0x00000020 */
+#define GPIO_PUPDR_PUPDR3_Pos (6U)
+#define GPIO_PUPDR_PUPDR3_Msk (0x3U << GPIO_PUPDR_PUPDR3_Pos) /*!< 0x000000C0 */
+#define GPIO_PUPDR_PUPDR3 GPIO_PUPDR_PUPDR3_Msk
+#define GPIO_PUPDR_PUPDR3_0 (0x1U << GPIO_PUPDR_PUPDR3_Pos) /*!< 0x00000040 */
+#define GPIO_PUPDR_PUPDR3_1 (0x2U << GPIO_PUPDR_PUPDR3_Pos) /*!< 0x00000080 */
+#define GPIO_PUPDR_PUPDR4_Pos (8U)
+#define GPIO_PUPDR_PUPDR4_Msk (0x3U << GPIO_PUPDR_PUPDR4_Pos) /*!< 0x00000300 */
+#define GPIO_PUPDR_PUPDR4 GPIO_PUPDR_PUPDR4_Msk
+#define GPIO_PUPDR_PUPDR4_0 (0x1U << GPIO_PUPDR_PUPDR4_Pos) /*!< 0x00000100 */
+#define GPIO_PUPDR_PUPDR4_1 (0x2U << GPIO_PUPDR_PUPDR4_Pos) /*!< 0x00000200 */
+#define GPIO_PUPDR_PUPDR5_Pos (10U)
+#define GPIO_PUPDR_PUPDR5_Msk (0x3U << GPIO_PUPDR_PUPDR5_Pos) /*!< 0x00000C00 */
+#define GPIO_PUPDR_PUPDR5 GPIO_PUPDR_PUPDR5_Msk
+#define GPIO_PUPDR_PUPDR5_0 (0x1U << GPIO_PUPDR_PUPDR5_Pos) /*!< 0x00000400 */
+#define GPIO_PUPDR_PUPDR5_1 (0x2U << GPIO_PUPDR_PUPDR5_Pos) /*!< 0x00000800 */
+#define GPIO_PUPDR_PUPDR6_Pos (12U)
+#define GPIO_PUPDR_PUPDR6_Msk (0x3U << GPIO_PUPDR_PUPDR6_Pos) /*!< 0x00003000 */
+#define GPIO_PUPDR_PUPDR6 GPIO_PUPDR_PUPDR6_Msk
+#define GPIO_PUPDR_PUPDR6_0 (0x1U << GPIO_PUPDR_PUPDR6_Pos) /*!< 0x00001000 */
+#define GPIO_PUPDR_PUPDR6_1 (0x2U << GPIO_PUPDR_PUPDR6_Pos) /*!< 0x00002000 */
+#define GPIO_PUPDR_PUPDR7_Pos (14U)
+#define GPIO_PUPDR_PUPDR7_Msk (0x3U << GPIO_PUPDR_PUPDR7_Pos) /*!< 0x0000C000 */
+#define GPIO_PUPDR_PUPDR7 GPIO_PUPDR_PUPDR7_Msk
+#define GPIO_PUPDR_PUPDR7_0 (0x1U << GPIO_PUPDR_PUPDR7_Pos) /*!< 0x00004000 */
+#define GPIO_PUPDR_PUPDR7_1 (0x2U << GPIO_PUPDR_PUPDR7_Pos) /*!< 0x00008000 */
+#define GPIO_PUPDR_PUPDR8_Pos (16U)
+#define GPIO_PUPDR_PUPDR8_Msk (0x3U << GPIO_PUPDR_PUPDR8_Pos) /*!< 0x00030000 */
+#define GPIO_PUPDR_PUPDR8 GPIO_PUPDR_PUPDR8_Msk
+#define GPIO_PUPDR_PUPDR8_0 (0x1U << GPIO_PUPDR_PUPDR8_Pos) /*!< 0x00010000 */
+#define GPIO_PUPDR_PUPDR8_1 (0x2U << GPIO_PUPDR_PUPDR8_Pos) /*!< 0x00020000 */
+#define GPIO_PUPDR_PUPDR9_Pos (18U)
+#define GPIO_PUPDR_PUPDR9_Msk (0x3U << GPIO_PUPDR_PUPDR9_Pos) /*!< 0x000C0000 */
+#define GPIO_PUPDR_PUPDR9 GPIO_PUPDR_PUPDR9_Msk
+#define GPIO_PUPDR_PUPDR9_0 (0x1U << GPIO_PUPDR_PUPDR9_Pos) /*!< 0x00040000 */
+#define GPIO_PUPDR_PUPDR9_1 (0x2U << GPIO_PUPDR_PUPDR9_Pos) /*!< 0x00080000 */
+#define GPIO_PUPDR_PUPDR10_Pos (20U)
+#define GPIO_PUPDR_PUPDR10_Msk (0x3U << GPIO_PUPDR_PUPDR10_Pos) /*!< 0x00300000 */
+#define GPIO_PUPDR_PUPDR10 GPIO_PUPDR_PUPDR10_Msk
+#define GPIO_PUPDR_PUPDR10_0 (0x1U << GPIO_PUPDR_PUPDR10_Pos) /*!< 0x00100000 */
+#define GPIO_PUPDR_PUPDR10_1 (0x2U << GPIO_PUPDR_PUPDR10_Pos) /*!< 0x00200000 */
+#define GPIO_PUPDR_PUPDR11_Pos (22U)
+#define GPIO_PUPDR_PUPDR11_Msk (0x3U << GPIO_PUPDR_PUPDR11_Pos) /*!< 0x00C00000 */
+#define GPIO_PUPDR_PUPDR11 GPIO_PUPDR_PUPDR11_Msk
+#define GPIO_PUPDR_PUPDR11_0 (0x1U << GPIO_PUPDR_PUPDR11_Pos) /*!< 0x00400000 */
+#define GPIO_PUPDR_PUPDR11_1 (0x2U << GPIO_PUPDR_PUPDR11_Pos) /*!< 0x00800000 */
+#define GPIO_PUPDR_PUPDR12_Pos (24U)
+#define GPIO_PUPDR_PUPDR12_Msk (0x3U << GPIO_PUPDR_PUPDR12_Pos) /*!< 0x03000000 */
+#define GPIO_PUPDR_PUPDR12 GPIO_PUPDR_PUPDR12_Msk
+#define GPIO_PUPDR_PUPDR12_0 (0x1U << GPIO_PUPDR_PUPDR12_Pos) /*!< 0x01000000 */
+#define GPIO_PUPDR_PUPDR12_1 (0x2U << GPIO_PUPDR_PUPDR12_Pos) /*!< 0x02000000 */
+#define GPIO_PUPDR_PUPDR13_Pos (26U)
+#define GPIO_PUPDR_PUPDR13_Msk (0x3U << GPIO_PUPDR_PUPDR13_Pos) /*!< 0x0C000000 */
+#define GPIO_PUPDR_PUPDR13 GPIO_PUPDR_PUPDR13_Msk
+#define GPIO_PUPDR_PUPDR13_0 (0x1U << GPIO_PUPDR_PUPDR13_Pos) /*!< 0x04000000 */
+#define GPIO_PUPDR_PUPDR13_1 (0x2U << GPIO_PUPDR_PUPDR13_Pos) /*!< 0x08000000 */
+#define GPIO_PUPDR_PUPDR14_Pos (28U)
+#define GPIO_PUPDR_PUPDR14_Msk (0x3U << GPIO_PUPDR_PUPDR14_Pos) /*!< 0x30000000 */
+#define GPIO_PUPDR_PUPDR14 GPIO_PUPDR_PUPDR14_Msk
+#define GPIO_PUPDR_PUPDR14_0 (0x1U << GPIO_PUPDR_PUPDR14_Pos) /*!< 0x10000000 */
+#define GPIO_PUPDR_PUPDR14_1 (0x2U << GPIO_PUPDR_PUPDR14_Pos) /*!< 0x20000000 */
+#define GPIO_PUPDR_PUPDR15_Pos (30U)
+#define GPIO_PUPDR_PUPDR15_Msk (0x3U << GPIO_PUPDR_PUPDR15_Pos) /*!< 0xC0000000 */
+#define GPIO_PUPDR_PUPDR15 GPIO_PUPDR_PUPDR15_Msk
+#define GPIO_PUPDR_PUPDR15_0 (0x1U << GPIO_PUPDR_PUPDR15_Pos) /*!< 0x40000000 */
+#define GPIO_PUPDR_PUPDR15_1 (0x2U << GPIO_PUPDR_PUPDR15_Pos) /*!< 0x80000000 */
+
+/******************* Bit definition for GPIO_IDR register *******************/
+#define GPIO_IDR_0 (0x00000001U)
+#define GPIO_IDR_1 (0x00000002U)
+#define GPIO_IDR_2 (0x00000004U)
+#define GPIO_IDR_3 (0x00000008U)
+#define GPIO_IDR_4 (0x00000010U)
+#define GPIO_IDR_5 (0x00000020U)
+#define GPIO_IDR_6 (0x00000040U)
+#define GPIO_IDR_7 (0x00000080U)
+#define GPIO_IDR_8 (0x00000100U)
+#define GPIO_IDR_9 (0x00000200U)
+#define GPIO_IDR_10 (0x00000400U)
+#define GPIO_IDR_11 (0x00000800U)
+#define GPIO_IDR_12 (0x00001000U)
+#define GPIO_IDR_13 (0x00002000U)
+#define GPIO_IDR_14 (0x00004000U)
+#define GPIO_IDR_15 (0x00008000U)
+
+/****************** Bit definition for GPIO_ODR register ********************/
+#define GPIO_ODR_0 (0x00000001U)
+#define GPIO_ODR_1 (0x00000002U)
+#define GPIO_ODR_2 (0x00000004U)
+#define GPIO_ODR_3 (0x00000008U)
+#define GPIO_ODR_4 (0x00000010U)
+#define GPIO_ODR_5 (0x00000020U)
+#define GPIO_ODR_6 (0x00000040U)
+#define GPIO_ODR_7 (0x00000080U)
+#define GPIO_ODR_8 (0x00000100U)
+#define GPIO_ODR_9 (0x00000200U)
+#define GPIO_ODR_10 (0x00000400U)
+#define GPIO_ODR_11 (0x00000800U)
+#define GPIO_ODR_12 (0x00001000U)
+#define GPIO_ODR_13 (0x00002000U)
+#define GPIO_ODR_14 (0x00004000U)
+#define GPIO_ODR_15 (0x00008000U)
+
+/****************** Bit definition for GPIO_BSRR register ********************/
+#define GPIO_BSRR_BS_0 (0x00000001U)
+#define GPIO_BSRR_BS_1 (0x00000002U)
+#define GPIO_BSRR_BS_2 (0x00000004U)
+#define GPIO_BSRR_BS_3 (0x00000008U)
+#define GPIO_BSRR_BS_4 (0x00000010U)
+#define GPIO_BSRR_BS_5 (0x00000020U)
+#define GPIO_BSRR_BS_6 (0x00000040U)
+#define GPIO_BSRR_BS_7 (0x00000080U)
+#define GPIO_BSRR_BS_8 (0x00000100U)
+#define GPIO_BSRR_BS_9 (0x00000200U)
+#define GPIO_BSRR_BS_10 (0x00000400U)
+#define GPIO_BSRR_BS_11 (0x00000800U)
+#define GPIO_BSRR_BS_12 (0x00001000U)
+#define GPIO_BSRR_BS_13 (0x00002000U)
+#define GPIO_BSRR_BS_14 (0x00004000U)
+#define GPIO_BSRR_BS_15 (0x00008000U)
+#define GPIO_BSRR_BR_0 (0x00010000U)
+#define GPIO_BSRR_BR_1 (0x00020000U)
+#define GPIO_BSRR_BR_2 (0x00040000U)
+#define GPIO_BSRR_BR_3 (0x00080000U)
+#define GPIO_BSRR_BR_4 (0x00100000U)
+#define GPIO_BSRR_BR_5 (0x00200000U)
+#define GPIO_BSRR_BR_6 (0x00400000U)
+#define GPIO_BSRR_BR_7 (0x00800000U)
+#define GPIO_BSRR_BR_8 (0x01000000U)
+#define GPIO_BSRR_BR_9 (0x02000000U)
+#define GPIO_BSRR_BR_10 (0x04000000U)
+#define GPIO_BSRR_BR_11 (0x08000000U)
+#define GPIO_BSRR_BR_12 (0x10000000U)
+#define GPIO_BSRR_BR_13 (0x20000000U)
+#define GPIO_BSRR_BR_14 (0x40000000U)
+#define GPIO_BSRR_BR_15 (0x80000000U)
+
+/****************** Bit definition for GPIO_LCKR register ********************/
+#define GPIO_LCKR_LCK0_Pos (0U)
+#define GPIO_LCKR_LCK0_Msk (0x1U << GPIO_LCKR_LCK0_Pos) /*!< 0x00000001 */
+#define GPIO_LCKR_LCK0 GPIO_LCKR_LCK0_Msk
+#define GPIO_LCKR_LCK1_Pos (1U)
+#define GPIO_LCKR_LCK1_Msk (0x1U << GPIO_LCKR_LCK1_Pos) /*!< 0x00000002 */
+#define GPIO_LCKR_LCK1 GPIO_LCKR_LCK1_Msk
+#define GPIO_LCKR_LCK2_Pos (2U)
+#define GPIO_LCKR_LCK2_Msk (0x1U << GPIO_LCKR_LCK2_Pos) /*!< 0x00000004 */
+#define GPIO_LCKR_LCK2 GPIO_LCKR_LCK2_Msk
+#define GPIO_LCKR_LCK3_Pos (3U)
+#define GPIO_LCKR_LCK3_Msk (0x1U << GPIO_LCKR_LCK3_Pos) /*!< 0x00000008 */
+#define GPIO_LCKR_LCK3 GPIO_LCKR_LCK3_Msk
+#define GPIO_LCKR_LCK4_Pos (4U)
+#define GPIO_LCKR_LCK4_Msk (0x1U << GPIO_LCKR_LCK4_Pos) /*!< 0x00000010 */
+#define GPIO_LCKR_LCK4 GPIO_LCKR_LCK4_Msk
+#define GPIO_LCKR_LCK5_Pos (5U)
+#define GPIO_LCKR_LCK5_Msk (0x1U << GPIO_LCKR_LCK5_Pos) /*!< 0x00000020 */
+#define GPIO_LCKR_LCK5 GPIO_LCKR_LCK5_Msk
+#define GPIO_LCKR_LCK6_Pos (6U)
+#define GPIO_LCKR_LCK6_Msk (0x1U << GPIO_LCKR_LCK6_Pos) /*!< 0x00000040 */
+#define GPIO_LCKR_LCK6 GPIO_LCKR_LCK6_Msk
+#define GPIO_LCKR_LCK7_Pos (7U)
+#define GPIO_LCKR_LCK7_Msk (0x1U << GPIO_LCKR_LCK7_Pos) /*!< 0x00000080 */
+#define GPIO_LCKR_LCK7 GPIO_LCKR_LCK7_Msk
+#define GPIO_LCKR_LCK8_Pos (8U)
+#define GPIO_LCKR_LCK8_Msk (0x1U << GPIO_LCKR_LCK8_Pos) /*!< 0x00000100 */
+#define GPIO_LCKR_LCK8 GPIO_LCKR_LCK8_Msk
+#define GPIO_LCKR_LCK9_Pos (9U)
+#define GPIO_LCKR_LCK9_Msk (0x1U << GPIO_LCKR_LCK9_Pos) /*!< 0x00000200 */
+#define GPIO_LCKR_LCK9 GPIO_LCKR_LCK9_Msk
+#define GPIO_LCKR_LCK10_Pos (10U)
+#define GPIO_LCKR_LCK10_Msk (0x1U << GPIO_LCKR_LCK10_Pos) /*!< 0x00000400 */
+#define GPIO_LCKR_LCK10 GPIO_LCKR_LCK10_Msk
+#define GPIO_LCKR_LCK11_Pos (11U)
+#define GPIO_LCKR_LCK11_Msk (0x1U << GPIO_LCKR_LCK11_Pos) /*!< 0x00000800 */
+#define GPIO_LCKR_LCK11 GPIO_LCKR_LCK11_Msk
+#define GPIO_LCKR_LCK12_Pos (12U)
+#define GPIO_LCKR_LCK12_Msk (0x1U << GPIO_LCKR_LCK12_Pos) /*!< 0x00001000 */
+#define GPIO_LCKR_LCK12 GPIO_LCKR_LCK12_Msk
+#define GPIO_LCKR_LCK13_Pos (13U)
+#define GPIO_LCKR_LCK13_Msk (0x1U << GPIO_LCKR_LCK13_Pos) /*!< 0x00002000 */
+#define GPIO_LCKR_LCK13 GPIO_LCKR_LCK13_Msk
+#define GPIO_LCKR_LCK14_Pos (14U)
+#define GPIO_LCKR_LCK14_Msk (0x1U << GPIO_LCKR_LCK14_Pos) /*!< 0x00004000 */
+#define GPIO_LCKR_LCK14 GPIO_LCKR_LCK14_Msk
+#define GPIO_LCKR_LCK15_Pos (15U)
+#define GPIO_LCKR_LCK15_Msk (0x1U << GPIO_LCKR_LCK15_Pos) /*!< 0x00008000 */
+#define GPIO_LCKR_LCK15 GPIO_LCKR_LCK15_Msk
+#define GPIO_LCKR_LCKK_Pos (16U)
+#define GPIO_LCKR_LCKK_Msk (0x1U << GPIO_LCKR_LCKK_Pos) /*!< 0x00010000 */
+#define GPIO_LCKR_LCKK GPIO_LCKR_LCKK_Msk
+
+/****************** Bit definition for GPIO_AFRL register ********************/
+#define GPIO_AFRL_AFSEL0_Pos (0U)
+#define GPIO_AFRL_AFSEL0_Msk (0xFU << GPIO_AFRL_AFSEL0_Pos) /*!< 0x0000000F */
+#define GPIO_AFRL_AFSEL0 GPIO_AFRL_AFSEL0_Msk
+#define GPIO_AFRL_AFSEL1_Pos (4U)
+#define GPIO_AFRL_AFSEL1_Msk (0xFU << GPIO_AFRL_AFSEL1_Pos) /*!< 0x000000F0 */
+#define GPIO_AFRL_AFSEL1 GPIO_AFRL_AFSEL1_Msk
+#define GPIO_AFRL_AFSEL2_Pos (8U)
+#define GPIO_AFRL_AFSEL2_Msk (0xFU << GPIO_AFRL_AFSEL2_Pos) /*!< 0x00000F00 */
+#define GPIO_AFRL_AFSEL2 GPIO_AFRL_AFSEL2_Msk
+#define GPIO_AFRL_AFSEL3_Pos (12U)
+#define GPIO_AFRL_AFSEL3_Msk (0xFU << GPIO_AFRL_AFSEL3_Pos) /*!< 0x0000F000 */
+#define GPIO_AFRL_AFSEL3 GPIO_AFRL_AFSEL3_Msk
+#define GPIO_AFRL_AFSEL4_Pos (16U)
+#define GPIO_AFRL_AFSEL4_Msk (0xFU << GPIO_AFRL_AFSEL4_Pos) /*!< 0x000F0000 */
+#define GPIO_AFRL_AFSEL4 GPIO_AFRL_AFSEL4_Msk
+#define GPIO_AFRL_AFSEL5_Pos (20U)
+#define GPIO_AFRL_AFSEL5_Msk (0xFU << GPIO_AFRL_AFSEL5_Pos) /*!< 0x00F00000 */
+#define GPIO_AFRL_AFSEL5 GPIO_AFRL_AFSEL5_Msk
+#define GPIO_AFRL_AFSEL6_Pos (24U)
+#define GPIO_AFRL_AFSEL6_Msk (0xFU << GPIO_AFRL_AFSEL6_Pos) /*!< 0x0F000000 */
+#define GPIO_AFRL_AFSEL6 GPIO_AFRL_AFSEL6_Msk
+#define GPIO_AFRL_AFSEL7_Pos (28U)
+#define GPIO_AFRL_AFSEL7_Msk (0xFU << GPIO_AFRL_AFSEL7_Pos) /*!< 0xF0000000 */
+#define GPIO_AFRL_AFSEL7 GPIO_AFRL_AFSEL7_Msk
+
+/* Legacy aliases */
+#define GPIO_AFRL_AFRL0_Pos GPIO_AFRL_AFSEL0_Pos
+#define GPIO_AFRL_AFRL0_Msk GPIO_AFRL_AFSEL0_Msk
+#define GPIO_AFRL_AFRL0 GPIO_AFRL_AFSEL0
+#define GPIO_AFRL_AFRL1_Pos GPIO_AFRL_AFSEL1_Pos
+#define GPIO_AFRL_AFRL1_Msk GPIO_AFRL_AFSEL1_Msk
+#define GPIO_AFRL_AFRL1 GPIO_AFRL_AFSEL1
+#define GPIO_AFRL_AFRL2_Pos GPIO_AFRL_AFSEL2_Pos
+#define GPIO_AFRL_AFRL2_Msk GPIO_AFRL_AFSEL2_Msk
+#define GPIO_AFRL_AFRL2 GPIO_AFRL_AFSEL2
+#define GPIO_AFRL_AFRL3_Pos GPIO_AFRL_AFSEL3_Pos
+#define GPIO_AFRL_AFRL3_Msk GPIO_AFRL_AFSEL3_Msk
+#define GPIO_AFRL_AFRL3 GPIO_AFRL_AFSEL3
+#define GPIO_AFRL_AFRL4_Pos GPIO_AFRL_AFSEL4_Pos
+#define GPIO_AFRL_AFRL4_Msk GPIO_AFRL_AFSEL4_Msk
+#define GPIO_AFRL_AFRL4 GPIO_AFRL_AFSEL4
+#define GPIO_AFRL_AFRL5_Pos GPIO_AFRL_AFSEL5_Pos
+#define GPIO_AFRL_AFRL5_Msk GPIO_AFRL_AFSEL5_Msk
+#define GPIO_AFRL_AFRL5 GPIO_AFRL_AFSEL5
+#define GPIO_AFRL_AFRL6_Pos GPIO_AFRL_AFSEL6_Pos
+#define GPIO_AFRL_AFRL6_Msk GPIO_AFRL_AFSEL6_Msk
+#define GPIO_AFRL_AFRL6 GPIO_AFRL_AFSEL6
+#define GPIO_AFRL_AFRL7_Pos GPIO_AFRL_AFSEL7_Pos
+#define GPIO_AFRL_AFRL7_Msk GPIO_AFRL_AFSEL7_Msk
+#define GPIO_AFRL_AFRL7 GPIO_AFRL_AFSEL7
+
+/****************** Bit definition for GPIO_AFRH register ********************/
+#define GPIO_AFRH_AFSEL8_Pos (0U)
+#define GPIO_AFRH_AFSEL8_Msk (0xFU << GPIO_AFRH_AFSEL8_Pos) /*!< 0x0000000F */
+#define GPIO_AFRH_AFSEL8 GPIO_AFRH_AFSEL8_Msk
+#define GPIO_AFRH_AFSEL9_Pos (4U)
+#define GPIO_AFRH_AFSEL9_Msk (0xFU << GPIO_AFRH_AFSEL9_Pos) /*!< 0x000000F0 */
+#define GPIO_AFRH_AFSEL9 GPIO_AFRH_AFSEL9_Msk
+#define GPIO_AFRH_AFSEL10_Pos (8U)
+#define GPIO_AFRH_AFSEL10_Msk (0xFU << GPIO_AFRH_AFSEL10_Pos) /*!< 0x00000F00 */
+#define GPIO_AFRH_AFSEL10 GPIO_AFRH_AFSEL10_Msk
+#define GPIO_AFRH_AFSEL11_Pos (12U)
+#define GPIO_AFRH_AFSEL11_Msk (0xFU << GPIO_AFRH_AFSEL11_Pos) /*!< 0x0000F000 */
+#define GPIO_AFRH_AFSEL11 GPIO_AFRH_AFSEL11_Msk
+#define GPIO_AFRH_AFSEL12_Pos (16U)
+#define GPIO_AFRH_AFSEL12_Msk (0xFU << GPIO_AFRH_AFSEL12_Pos) /*!< 0x000F0000 */
+#define GPIO_AFRH_AFSEL12 GPIO_AFRH_AFSEL12_Msk
+#define GPIO_AFRH_AFSEL13_Pos (20U)
+#define GPIO_AFRH_AFSEL13_Msk (0xFU << GPIO_AFRH_AFSEL13_Pos) /*!< 0x00F00000 */
+#define GPIO_AFRH_AFSEL13 GPIO_AFRH_AFSEL13_Msk
+#define GPIO_AFRH_AFSEL14_Pos (24U)
+#define GPIO_AFRH_AFSEL14_Msk (0xFU << GPIO_AFRH_AFSEL14_Pos) /*!< 0x0F000000 */
+#define GPIO_AFRH_AFSEL14 GPIO_AFRH_AFSEL14_Msk
+#define GPIO_AFRH_AFSEL15_Pos (28U)
+#define GPIO_AFRH_AFSEL15_Msk (0xFU << GPIO_AFRH_AFSEL15_Pos) /*!< 0xF0000000 */
+#define GPIO_AFRH_AFSEL15 GPIO_AFRH_AFSEL15_Msk
+
+/* Legacy aliases */
+#define GPIO_AFRH_AFRH0_Pos GPIO_AFRH_AFSEL8_Pos
+#define GPIO_AFRH_AFRH0_Msk GPIO_AFRH_AFSEL8_Msk
+#define GPIO_AFRH_AFRH0 GPIO_AFRH_AFSEL8
+#define GPIO_AFRH_AFRH1_Pos GPIO_AFRH_AFSEL9_Pos
+#define GPIO_AFRH_AFRH1_Msk GPIO_AFRH_AFSEL9_Msk
+#define GPIO_AFRH_AFRH1 GPIO_AFRH_AFSEL9
+#define GPIO_AFRH_AFRH2_Pos GPIO_AFRH_AFSEL10_Pos
+#define GPIO_AFRH_AFRH2_Msk GPIO_AFRH_AFSEL10_Msk
+#define GPIO_AFRH_AFRH2 GPIO_AFRH_AFSEL10
+#define GPIO_AFRH_AFRH3_Pos GPIO_AFRH_AFSEL11_Pos
+#define GPIO_AFRH_AFRH3_Msk GPIO_AFRH_AFSEL11_Msk
+#define GPIO_AFRH_AFRH3 GPIO_AFRH_AFSEL11
+#define GPIO_AFRH_AFRH4_Pos GPIO_AFRH_AFSEL12_Pos
+#define GPIO_AFRH_AFRH4_Msk GPIO_AFRH_AFSEL12_Msk
+#define GPIO_AFRH_AFRH4 GPIO_AFRH_AFSEL12
+#define GPIO_AFRH_AFRH5_Pos GPIO_AFRH_AFSEL13_Pos
+#define GPIO_AFRH_AFRH5_Msk GPIO_AFRH_AFSEL13_Msk
+#define GPIO_AFRH_AFRH5 GPIO_AFRH_AFSEL13
+#define GPIO_AFRH_AFRH6_Pos GPIO_AFRH_AFSEL14_Pos
+#define GPIO_AFRH_AFRH6_Msk GPIO_AFRH_AFSEL14_Msk
+#define GPIO_AFRH_AFRH6 GPIO_AFRH_AFSEL14
+#define GPIO_AFRH_AFRH7_Pos GPIO_AFRH_AFSEL15_Pos
+#define GPIO_AFRH_AFRH7_Msk GPIO_AFRH_AFSEL15_Msk
+#define GPIO_AFRH_AFRH7 GPIO_AFRH_AFSEL15
+
+/****************** Bit definition for GPIO_BRR register *********************/
+#define GPIO_BRR_BR_0 (0x00000001U)
+#define GPIO_BRR_BR_1 (0x00000002U)
+#define GPIO_BRR_BR_2 (0x00000004U)
+#define GPIO_BRR_BR_3 (0x00000008U)
+#define GPIO_BRR_BR_4 (0x00000010U)
+#define GPIO_BRR_BR_5 (0x00000020U)
+#define GPIO_BRR_BR_6 (0x00000040U)
+#define GPIO_BRR_BR_7 (0x00000080U)
+#define GPIO_BRR_BR_8 (0x00000100U)
+#define GPIO_BRR_BR_9 (0x00000200U)
+#define GPIO_BRR_BR_10 (0x00000400U)
+#define GPIO_BRR_BR_11 (0x00000800U)
+#define GPIO_BRR_BR_12 (0x00001000U)
+#define GPIO_BRR_BR_13 (0x00002000U)
+#define GPIO_BRR_BR_14 (0x00004000U)
+#define GPIO_BRR_BR_15 (0x00008000U)
+
+/******************************************************************************/
+/* */
+/* Inter-integrated Circuit Interface (I2C) */
+/* */
+/******************************************************************************/
+
+/******************* Bit definition for I2C_CR1 register *******************/
+#define I2C_CR1_PE_Pos (0U)
+#define I2C_CR1_PE_Msk (0x1U << I2C_CR1_PE_Pos) /*!< 0x00000001 */
+#define I2C_CR1_PE I2C_CR1_PE_Msk /*!< Peripheral enable */
+#define I2C_CR1_TXIE_Pos (1U)
+#define I2C_CR1_TXIE_Msk (0x1U << I2C_CR1_TXIE_Pos) /*!< 0x00000002 */
+#define I2C_CR1_TXIE I2C_CR1_TXIE_Msk /*!< TX interrupt enable */
+#define I2C_CR1_RXIE_Pos (2U)
+#define I2C_CR1_RXIE_Msk (0x1U << I2C_CR1_RXIE_Pos) /*!< 0x00000004 */
+#define I2C_CR1_RXIE I2C_CR1_RXIE_Msk /*!< RX interrupt enable */
+#define I2C_CR1_ADDRIE_Pos (3U)
+#define I2C_CR1_ADDRIE_Msk (0x1U << I2C_CR1_ADDRIE_Pos) /*!< 0x00000008 */
+#define I2C_CR1_ADDRIE I2C_CR1_ADDRIE_Msk /*!< Address match interrupt enable */
+#define I2C_CR1_NACKIE_Pos (4U)
+#define I2C_CR1_NACKIE_Msk (0x1U << I2C_CR1_NACKIE_Pos) /*!< 0x00000010 */
+#define I2C_CR1_NACKIE I2C_CR1_NACKIE_Msk /*!< NACK received interrupt enable */
+#define I2C_CR1_STOPIE_Pos (5U)
+#define I2C_CR1_STOPIE_Msk (0x1U << I2C_CR1_STOPIE_Pos) /*!< 0x00000020 */
+#define I2C_CR1_STOPIE I2C_CR1_STOPIE_Msk /*!< STOP detection interrupt enable */
+#define I2C_CR1_TCIE_Pos (6U)
+#define I2C_CR1_TCIE_Msk (0x1U << I2C_CR1_TCIE_Pos) /*!< 0x00000040 */
+#define I2C_CR1_TCIE I2C_CR1_TCIE_Msk /*!< Transfer complete interrupt enable */
+#define I2C_CR1_ERRIE_Pos (7U)
+#define I2C_CR1_ERRIE_Msk (0x1U << I2C_CR1_ERRIE_Pos) /*!< 0x00000080 */
+#define I2C_CR1_ERRIE I2C_CR1_ERRIE_Msk /*!< Errors interrupt enable */
+#define I2C_CR1_DNF_Pos (8U)
+#define I2C_CR1_DNF_Msk (0xFU << I2C_CR1_DNF_Pos) /*!< 0x00000F00 */
+#define I2C_CR1_DNF I2C_CR1_DNF_Msk /*!< Digital noise filter */
+#define I2C_CR1_ANFOFF_Pos (12U)
+#define I2C_CR1_ANFOFF_Msk (0x1U << I2C_CR1_ANFOFF_Pos) /*!< 0x00001000 */
+#define I2C_CR1_ANFOFF I2C_CR1_ANFOFF_Msk /*!< Analog noise filter OFF */
+#define I2C_CR1_SBC_Pos (16U)
+#define I2C_CR1_SBC_Msk (0x1U << I2C_CR1_SBC_Pos) /*!< 0x00010000 */
+#define I2C_CR1_SBC I2C_CR1_SBC_Msk /*!< Slave byte control */
+#define I2C_CR1_NOSTRETCH_Pos (17U)
+#define I2C_CR1_NOSTRETCH_Msk (0x1U << I2C_CR1_NOSTRETCH_Pos) /*!< 0x00020000 */
+#define I2C_CR1_NOSTRETCH I2C_CR1_NOSTRETCH_Msk /*!< Clock stretching disable */
+#define I2C_CR1_WUPEN_Pos (18U) /*!<>*/
+#define I2C_CR1_WUPEN_Msk (0x1U<CR |= (uint32_t)0x00000001;
+
+ /* Reset SW[1:0], HPRE[3:0], PPRE[2:0] and MCOSEL[2:0] bits */
+ RCC->CFGR &= (uint32_t)0xF8FFB81C;
+
+ /* Reset USARTSW[1:0], I2CSW bits */
+ RCC->CFGR3 &= (uint32_t)0xFFFFFFEC;
+
+ /* Disable all interrupts */
+ RCC->CIR = 0x00000000;
+
+ SetSysClock();
+
+#ifdef VECT_TAB_SRAM
+ SYSCFG->CFGR1 |= SYSCFG_CFGR1_MEM_MODE; /* Vector Table Relocation in Internal SRAM. */
+#else
+ FLASH->INT_VEC_OFFSET = VECT_TAB_OFFSET ; /* Vector Table Relocation in Internal FLASH. */
+#endif
+}
+
+
+/**
+ * @brief Configures the System clock frequency, HCLK, PCLK prescalers.
+ * @param None
+ * @retval None
+ */
+static void SetSysClock(void)
+{
+ /*reload the hsi trimming value to the bit3~bit13 of RCC_CR register */
+ uint32_t u32HSIFLASH = 0;
+ uint32_t u32RCC_CR = 0;
+ uint32_t u32HSITemp = 0;
+ uint16_t u16HSITempH = 0;
+ uint16_t u16HSITempL = 0;
+
+ u32HSIFLASH = *(uint32_t *) 0x1FFFF820;
+ u16HSITempH = (uint16_t)(u32HSIFLASH>>16);
+ u16HSITempL = (uint16_t)(u32HSIFLASH);
+
+ if(!(u16HSITempH & u16HSITempL))
+ {
+ u32HSITemp = RCC->CR;
+ u32HSITemp &= (uint32_t)((uint32_t)~(RCC_CR_HSITRIM|RCC_CR_HSICAL));
+ u32RCC_CR = (uint32_t)(((u16HSITempL & 0x001F) <<3) | (((u16HSITempL>>5) & 0x003F)<<8));
+ RCC->CR |= u32RCC_CR;
+ }
+ /*end*/
+#if(SYSCLK_SOURCE==SYSCLK_SRC_HSI8M)
+ SetSysClockToHSI();
+#elif(SYSCLK_SOURCE == SYSCLK_SRC_HSI16M)
+ SetSysClockToHSI();
+#elif(SYSCLK_SOURCE == SYSCLK_SRC_HSI32M)
+ SetSysClockToHSI();
+#elif(SYSCLK_SOURCE == SYSCLK_SRC_LSI)
+ SetSysClockToLSI();
+#elif(SYSCLK_SOURCE == SYSCLK_SCR_EXTCLK_IO)
+ SetSysClockToEXTCLK();
+#endif
+
+ /* If none of the define above is enabled, the HSI is used as System clock source (default after reset) */
+}
+
+#ifdef SYSCLK_FREQ_HSI
+static void SetSysClockToHSI(void)
+{
+ __IO uint32_t StartUpCounter = 0, HSIStatus = 0;
+ __IO uint32_t ACRreg = 0;
+ __IO uint32_t RCCHCLKReg = 0;
+ __IO uint32_t RCCPCLKReg = 0;
+
+ /* Enable HSI */
+ RCC->CR |= RCC_CR_HSION;
+
+ /* Set flash programming clock to 2MHz using HSI32M directly
+ * Datasheet and RM was updated in 2023 which derated flash programming from 4MHz
+ * 0x07 = 4MHz, 0x08 = 2MHz. change as you see fit */
+ RCC->CFGR4 &= ~(RCC_RCC_CFGR4_FLITFCLK_PRE | RCC_RCC_CFGR4_FLITFCLK_SE);
+ RCC->CFGR4 |= (((uint32_t)0x07) << RCC_RCC_CFGR4_FLITFCLK_PRE_Pos);
+
+ /* Wait until HSI is ready; if timeout is reached, then exit */
+ do {
+ HSIStatus = RCC->CR & RCC_CR_HSIRDY;
+ StartUpCounter++;
+ } while((HSIStatus == 0) && (StartUpCounter != HSI_STARTUP_TIMEOUT));
+
+ if ((RCC->CR & RCC_CR_HSIRDY) != RESET) {
+ HSIStatus = (uint32_t)0x01;
+ } else {
+ HSIStatus = (uint32_t)0x00;
+ }
+
+ if (HSIStatus == (uint32_t)0x01) {
+ /* Flash wait state */
+ ACRreg = FLASH->ACR;
+ ACRreg &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
+ FLASH->ACR = (uint32_t)(SET_FLASH_LATENCY | ACRreg);
+
+ /* HCLK = configured divided value from SYSCLK (which will later be set to HSI32M) */
+ RCCHCLKReg = RCC->CFGR;
+ RCCHCLKReg &= (uint32_t)((uint32_t)~RCC_CFGR_HPRE_Msk);
+ RCC->CFGR = (uint32_t)(SET_HPRE_DIV | RCCHCLKReg);
+
+ /* PCLK = HCLK */
+ RCCPCLKReg = RCC->CFGR;
+ RCCPCLKReg &= (uint32_t)((uint32_t)~RCC_CFGR_PPRE_Msk);
+ RCC->CFGR = (uint32_t)(RCC_CFGR_PPRE_DIV1|RCCPCLKReg);
+
+ /* Select HSI32M as system clock source */
+ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
+ RCC->CFGR |= (uint32_t)RCC_CFGR_SW_HSI;
+
+ /* Wait until HSI is active as system clock source */
+ while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI);
+ } else {
+ /* If clock fails to start, the application will have wrong clock configuration.
+ * User can add some code here to deal with this error
+ */
+ }
+}
+
+#elif (SYSCLK_SOURCE == SYSCLK_SRC_LSI)
+static void SetSysClockToLSI(void)
+{
+ __IO uint32_t StartUpCounter = 0, LSIStatus = 0;
+
+ /* Enable LSI */
+ RCC->CSR |= RCC_CSR_LSION;
+
+ /* Wait till LSI is ready and if Time out is reached exit */
+ do{
+ LSIStatus = RCC->CSR & RCC_CSR_LSIRDY;
+ StartUpCounter++;
+ } while((LSIStatus == 0) && (StartUpCounter != STARTUP_TIMEOUT));
+
+ if ((RCC->CSR & RCC_CSR_LSIRDY) != RESET)
+ {
+ LSIStatus = (uint32_t)0x01;
+ }
+ else
+ {
+ LSIStatus = (uint32_t)0x00;
+ }
+
+ if (LSIStatus == (uint32_t)0x01)
+ {
+
+ /* Flash wait state */
+ FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
+ FLASH->ACR |= (uint32_t)FLASH_Latency_0;
+
+ /* HCLK = SYSCLK */
+ RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
+
+ /* PCLK = HCLK */
+ RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE_DIV1;
+
+ /* Select HSI as system clock source */
+ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
+ RCC->CFGR |= (uint32_t)RCC_CFGR_SW_LSI;
+
+ /* Wait till LSI is used as system clock source */
+ while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != RCC_CFGR_SWS_LSI)
+ {
+ }
+
+ }
+ else
+ { /* If fails to start-up, the application will have wrong clock configuration. User can add here some code to deal with this error */
+ }
+};
+
+#elif (SYSCLK_SOURCE == SYSCLK_SCR_EXTCLK_IO)
+static void SetSysClockToEXTCLK(void)
+{
+ __IO uint32_t StartUpCounter = 0, EXTCLKStatus = 0;
+ __IO uint32_t ACRreg = 0;
+ __IO uint32_t RCCHCLKReg = 0;
+ __IO uint32_t RCCPCLKReg = 0;
+ //enable EXTIO PA1/PD7/PB5/PC5
+
+ /* Configure PA1 as CLOCK input */
+ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
+
+ GPIO_InitTypeDef GPIO_InitStructure;
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
+ GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
+ GPIO_Init(GPIOA, &GPIO_InitStructure);
+
+
+ // RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);
+ // GPIO_InitTypeDef GPIO_InitStructure;
+ // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
+ // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
+ // GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
+ // GPIO_Init(GPIOD, &GPIO_InitStructure);
+
+
+ // RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
+ // GPIO_InitTypeDef GPIO_InitStructure;
+ // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
+ // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
+ // GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
+ // GPIO_Init(GPIOB, &GPIO_InitStructure);
+
+ // RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
+ // GPIO_InitTypeDef GPIO_InitStructure;
+ // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
+ // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
+ // GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
+ // GPIO_Init(GPIOC, &GPIO_InitStructure);
+
+ /*CLOCK select */
+ RCC->CFGR4 &= (uint32_t)~(RCC_RCC_CFGR4_EXTCLK_SEL);
+ RCC->CFGR4 |= (uint32_t)RCC_CFGR4_EXTCLK_SEL_PA1;
+ // RCC->CFGR4 |= (uint32_t)RCC_CFGR4_EXTCLK_SEL_PB5;
+ // RCC->CFGR4 |= (uint32_t)RCC_CFGR4_EXTCLK_SEL_PC5;
+ // RCC->CFGR4 |= (uint32_t)RCC_CFGR4_EXTCLK_SEL_PD7;
+ /* Enable EXTCLK */
+ RCC->CR |= RCC_CR_EXTCLKON;
+
+ /* Wait till LSI is ready and if Time out is reached exit */
+ do{
+ EXTCLKStatus = RCC->CR & RCC_CR_EXTCLKRDY;
+ StartUpCounter++;
+ } while((EXTCLKStatus == 0) && (StartUpCounter != STARTUP_TIMEOUT));
+
+ if ((RCC->CR & RCC_CR_EXTCLKRDY) != RESET)
+ {
+ EXTCLKStatus = (uint32_t)0x01;
+ }
+ else
+ {
+ EXTCLKStatus = (uint32_t)0x00;
+ }
+
+ if (EXTCLKStatus == (uint32_t)0x01)
+ {
+
+ /* Flash wait state */
+ ACRreg= FLASH->ACR;
+ ACRreg &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
+
+ if (SystemCoreClock <= 16000000)
+ FLASH->ACR = (uint32_t)(FLASH_Latency_0|ACRreg);
+ else if(SystemCoreClock <= 32000000)
+ FLASH->ACR = (uint32_t)(FLASH_Latency_1|ACRreg);
+ else
+ FLASH->ACR = (uint32_t)(FLASH_Latency_2|ACRreg);
+
+
+ RCCHCLKReg = RCC->CFGR;
+ RCCHCLKReg &= (uint32_t)((uint32_t)~RCC_CFGR_HPRE_Msk);
+ /* HCLK = SYSCLK */
+ RCC->CFGR = (uint32_t)(RCC_CFGR_HPRE_DIV1|RCCHCLKReg);
+
+ RCCPCLKReg = RCC->CFGR;
+ RCCPCLKReg &= (uint32_t)((uint32_t)~RCC_CFGR_PPRE_Msk);
+ /* PCLK = HCLK */
+ RCC->CFGR = (uint32_t)(RCC_CFGR_PPRE_DIV1|RCCPCLKReg);
+
+
+ /* Select EXTCLK as system clock source */
+ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
+ RCC->CFGR |= (uint32_t)RCC_CFGR_SW_EXTCLK;
+
+ /* Wait till EXTCLK is used as system clock source */
+ while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != RCC_CFGR_SWS_EXTCLK)
+ {
+ }
+ }
+ else
+ { /* If fails to start-up, the application will have wrong clock configuration. User can add here some code to deal with this error */
+ }
+};
+
+#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.
+ * @param None
+ * @retval None
+ */
+void SystemCoreClockUpdate (void)
+{
+ uint32_t tmp = 0, presc = 0;
+
+ /* Get SYSCLK source -------------------------------------------------------*/
+ tmp = RCC->CFGR & RCC_CFGR_SWS;
+
+ switch (tmp)
+ {
+ case RCC_CFGR_SWS_HSI: /* HSI used as system clock */
+ SystemCoreClock = HCLK_FREQ;
+ break;
+ case RCC_CFGR_SWS_EXTCLK: /* EXTCLK used as system clock */
+ SystemCoreClock = EXTCLK_VALUE;
+ break;
+ case RCC_CFGR_SWS_LSI: /* LSI used as system clock */
+ SystemCoreClock = LSI_VALUE;
+ break;
+
+ default: /* HSI used as system clock */
+ SystemCoreClock = HCLK_FREQ;
+ break;
+ }
+
+ /* Compute HCLK clock frequency ----------------*/
+ /* Get HCLK prescaler */
+ tmp = RCC->CFGR & RCC_CFGR_HPRE;
+ tmp = tmp >> 4;
+ presc = AHBPrescTable[tmp];
+ /* HCLK clock frequency */
+ SystemCoreClock = SystemCoreClock/presc;
+}
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/Debug/systick_delay.c b/bootloader_hk32f030m_uart_xmodem/driver/Debug/systick_delay.c
new file mode 100644
index 0000000..051dddc
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/Debug/systick_delay.c
@@ -0,0 +1,71 @@
+#include "systick_delay.h"
+#include "hk32f030m.h"
+
+static uint32_t fac_us = 0;
+static uint32_t fac_ms = 0;
+
+/*******************************************************************************
+* Function Name : SysTick_Init
+* Description : SysTick Initialize
+* Input : none
+* Output : none
+* Return : none
+* Set SysTick clock source to 1/8 of HCLK
+*******************************************************************************/
+void SysTick_Init(void)
+{
+ SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
+ fac_us = SystemCoreClock / 8000000;
+ fac_ms = SystemCoreClock / 8000;
+}
+
+/*******************************************************************************
+* Function Name : SysTick_DelayUs
+* Description : delay by microseconds
+* Input : nus -- number of microseconds
+* Output : none
+* Return : none
+*******************************************************************************/
+void SysTick_DelayUs(uint32_t nus)
+{
+ uint32_t temp;
+
+ if (nus > 0)
+ {
+ SysTick->LOAD = nus * fac_us; // Set Reload Value
+ SysTick->VAL = 0x00; // Set Current Value to 0
+ SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; // Start counter
+ // Block when SysTick is running and counter flag not set
+ do
+ {
+ temp = SysTick->CTRL;
+ }
+ while ((temp & SysTick_CTRL_ENABLE_Msk) && !(temp & SysTick_CTRL_COUNTFLAG_Msk));
+ SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; // Stop counter
+ }
+}
+
+/*******************************************************************************
+* Function Name : SysTick_DelayMs
+* Description : Delay by milliseconds
+ SysTick->LOAD is 24-bit so the max delay = 0xFFFFFF*8*1000 / SYSCLK
+* Input : nms -- number of milliseconds
+*******************************************************************************/
+void SysTick_DelayMs(uint16_t nms)
+{
+ uint32_t temp;
+
+ if (nms > 0)
+ {
+ SysTick->LOAD = nms * fac_ms; // Set Reload Value (24-bit)
+ SysTick->VAL = 0x00; // Set Current Value to 0
+ SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; // Start counter
+ // Block when SysTick is running and counter flag not set
+ do
+ {
+ temp = SysTick->CTRL;
+ }
+ while ((temp & SysTick_CTRL_ENABLE_Msk) && !(temp & SysTick_CTRL_COUNTFLAG_Msk));
+ SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; // Stop counter
+ }
+}
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/Debug/systick_delay.h b/bootloader_hk32f030m_uart_xmodem/driver/Debug/systick_delay.h
new file mode 100644
index 0000000..988066d
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/Debug/systick_delay.h
@@ -0,0 +1,10 @@
+#ifndef __SYSTICK_H
+#define __SYSTICK_H
+
+#include "hk32f030m.h"
+
+void SysTick_Init(void);
+void SysTick_DelayUs(uint32_t nus);
+void SysTick_DelayMs(uint16_t nms);
+
+#endif
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/Debug/uart_printf.c b/bootloader_hk32f030m_uart_xmodem/driver/Debug/uart_printf.c
new file mode 100644
index 0000000..a63a596
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/Debug/uart_printf.c
@@ -0,0 +1,115 @@
+#include "uart_printf.h"
+
+#define UART_PRINTF_BAUDRATE 115200
+
+uint8_t HEX_TABLE[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
+
+void UART_PrintfInit(void)
+{
+ GPIO_InitTypeDef GPIO_InitStructure;
+ USART_InitTypeDef USART_InitStructure;
+
+#if UART_PORTx == UART_PORT_TX_A3_RX_D6
+ // Enable GPIO and UART clock
+ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOD, ENABLE);
+ RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
+ // AF config
+ GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_1);
+ GPIO_PinAFConfig(GPIOD, GPIO_PinSource6, GPIO_AF_1);
+ // PA3 As USART TX
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
+ GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
+ GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
+ GPIO_Init(GPIOA, &GPIO_InitStructure);
+ // PD6 As USART RX
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
+ GPIO_Init(GPIOD, &GPIO_InitStructure);
+
+#elif UART_PORTx == UART_PORT_TX_A3_RX_B4
+ // Enable GPIO and UART clock
+ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB, ENABLE);
+ RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
+ // AF config
+ GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_1); // TX
+ GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_4); // RX
+ // PA3 As USART TX
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
+ GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
+ GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
+ GPIO_Init(GPIOA, &GPIO_InitStructure);
+ // PB4 As USART RX
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
+ GPIO_Init(GPIOB, &GPIO_InitStructure);
+
+#endif
+ USART_InitStructure.USART_BaudRate = UART_PRINTF_BAUDRATE;
+ // 8-bit, 1 stop bit, no parity, no hardware flow control
+ USART_InitStructure.USART_WordLength = USART_WordLength_8b;
+ USART_InitStructure.USART_StopBits = USART_StopBits_1;
+ USART_InitStructure.USART_Parity = USART_Parity_No;
+ USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
+ // Enable Tx
+ USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
+ // Init and enable UART1
+ USART_Init(USART1, &USART_InitStructure);
+ USART_Cmd(USART1, ENABLE);
+}
+
+void UART_SendByte(uint8_t ch)
+{
+ /* Send one byte to USART */
+ USART_SendData(USART1, ch);
+ /* Block till tx empty flag is set */
+ while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
+}
+
+void UART_SendArray(uint8_t *array, uint16_t num)
+{
+ uint8_t i;
+ for (i = 0; i < num; i++)
+ {
+ UART_SendByte(array[i]);
+ }
+ /* Block till transmission is completed */
+ while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);
+}
+
+void UART_SendString(char *str)
+{
+ while (*str)
+ {
+ UART_SendByte(*str++);
+ }
+ /* Block till transmission is completed */
+ while (USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);
+}
+
+void UART_TxHex(uint8_t *hex, uint8_t len)
+{
+ while (len--)
+ {
+ UART_SendByte(HEX_TABLE[*(hex + len) >> 4 & 0xF]);
+ UART_SendByte(HEX_TABLE[*(hex + len) & 0xF]);
+ }
+}
+
+int __io_putchar(int ch)
+{
+ UART_SendByte((uint8_t)ch);
+ return ch;
+}
+
+__attribute__((weak)) int _write(int file, char *ptr, int len)
+{
+ (void)file;
+ int DataIdx;
+ for (DataIdx = 0; DataIdx < len; DataIdx++)
+ {
+ __io_putchar(*ptr++);
+ }
+ return len;
+}
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/Debug/uart_printf.h b/bootloader_hk32f030m_uart_xmodem/driver/Debug/uart_printf.h
new file mode 100644
index 0000000..b6346ac
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/Debug/uart_printf.h
@@ -0,0 +1,18 @@
+#ifndef __UART_PRINTF_H
+#define __UART_PRINTF_H
+
+#include "hk32f030m.h"
+#include "stdio.h"
+
+#define UART_PORT_TX_A3_RX_D6 0
+#define UART_PORT_TX_A3_RX_B4 1
+#define UART_PORTx UART_PORT_TX_A3_RX_D6
+
+void UART_PrintfInit(void);
+void UART_SendByte(uint8_t ch);
+void UART_SendHalfWord(uint16_t ch);
+void UART_SendArray(uint8_t *array, uint16_t num);
+void UART_SendString(char *str);
+void UART_TxHex(uint8_t *hex, uint8_t len);
+
+#endif
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/.gitkeep b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_adc.h b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_adc.h
new file mode 100644
index 0000000..f73da00
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_adc.h
@@ -0,0 +1,359 @@
+/**
+ ******************************************************************************
+ * @file hk32f030m_adc.h
+ * @version V1.0.0
+ * @date 2019-08-05
+ * @author Rakan.Z/Jane.li
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __HK32F030M_ADC_H
+#define __HK32F030M_ADC_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "hk32f030m.h"
+
+/** @addtogroup ADC
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+
+/**
+ * @brief ADC Init structure definition
+ */
+
+typedef struct
+{
+ FunctionalState ADC_ContinuousConvMode; /*!< Specifies whether the conversion is performed in
+ Continuous or Single mode.
+ This parameter can be set to ENABLE or DISABLE. */
+
+ uint32_t ADC_ExternalTrigConvEdge; /*!< Selects the external trigger Edge and enables the
+ trigger of a regular group. This parameter can be a value
+ of @ref ADC_external_trigger_edge_conversion */
+
+ uint32_t ADC_ExternalTrigConv; /*!< Defines the external trigger used to start the analog
+ to digital conversion of regular channels. This parameter
+ can be a value of @ref ADC_external_trigger_sources_for_channels_conversion */
+
+ uint32_t ADC_DataAlign; /*!< Specifies whether the ADC data alignment is left or right.
+ This parameter can be a value of @ref ADC_data_align */
+
+ uint32_t ADC_ScanDirection; /*!< Specifies in which direction the channels will be scanned
+ in the sequence.
+ This parameter can be a value of @ref ADC_Scan_Direction */
+}ADC_InitTypeDef;
+
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup ADC_Exported_Constants
+ * @{
+ */
+#define IS_ADC_ALL_PERIPH(PERIPH) ((PERIPH) == ADC1)
+
+/** @defgroup ADC_JitterOff
+ * @{
+ */
+/* These defines are obsolete and maintained for legacy purpose only. They are replaced by the ADC_ClockMode */
+#define ADC_JitterOff_PCLKDiv2 ADC_CFGR2_JITOFFDIV2
+#define ADC_JitterOff_PCLKDiv4 ADC_CFGR2_JITOFFDIV4
+
+#define IS_ADC_JITTEROFF(JITTEROFF) (((JITTEROFF) & 0x3FFFFFFF) == (uint32_t)RESET)
+
+/**
+ * @}
+ */
+
+/** @defgroup ADC_ClockMode
+ * @{
+ */
+#define ADC_ClockMode_AsynClk ((uint32_t)0x00000000) /*!< ADC Asynchronous clock mode */
+#define ADC_ClockMode_SynClkDiv2 ADC_CFGR2_CKMODE_0 /*!< Synchronous clock mode divided by 2 */
+#define ADC_ClockMode_SynClkDiv4 ADC_CFGR2_CKMODE_1 /*!< Synchronous clock mode divided by 4 */
+#define IS_ADC_CLOCKMODE(CLOCK) (((CLOCK) == ADC_ClockMode_AsynClk) ||\
+ ((CLOCK) == ADC_ClockMode_SynClkDiv2) ||\
+ ((CLOCK) == ADC_ClockMode_SynClkDiv4))
+
+/**
+ * @}
+ */
+
+/** @defgroup ADC_external_trigger_edge_conversion
+ * @{
+ */
+#define ADC_ExternalTrigConvEdge_None ((uint32_t)0x00000000)
+#define ADC_ExternalTrigConvEdge_Rising ADC_CFGR1_EXTEN_0
+#define ADC_ExternalTrigConvEdge_Falling ADC_CFGR1_EXTEN_1
+#define ADC_ExternalTrigConvEdge_RisingFalling ADC_CFGR1_EXTEN
+
+#define IS_ADC_EXT_TRIG_EDGE(EDGE) (((EDGE) == ADC_ExternalTrigConvEdge_None) || \
+ ((EDGE) == ADC_ExternalTrigConvEdge_Rising) || \
+ ((EDGE) == ADC_ExternalTrigConvEdge_Falling) || \
+ ((EDGE) == ADC_ExternalTrigConvEdge_RisingFalling))
+/**
+ * @}
+ */
+
+/** @defgroup ADC_external_trigger_sources_for_channels_conversion
+ * @{
+ */
+
+/* TIM1 */
+#define ADC_ExternalTrigConv_T1_TRGO ((uint32_t)0x00000000) //0
+#define ADC_ExternalTrigConv_T1_CC4 ADC_CFGR1_EXTSEL_0 //1
+#define ADC_ExternalTrigConv_T1_CC1 ADC_CFGR1_EXTSEL_2 //4
+#define ADC_ExternalTrigConv_T1_CC2 ((uint32_t)ADC_CFGR1_EXTSEL_2 | ADC_CFGR1_EXTSEL_0) //5
+#define ADC_ExternalTrigConv_T1_CC3 ((uint32_t)ADC_CFGR1_EXTSEL_2 | ADC_CFGR1_EXTSEL_1) //6
+
+/* TIM2 */
+#define ADC_ExternalTrigConv_T2_TRGO ADC_CFGR1_EXTSEL_1 //2
+
+/* TIM6 */
+#define ADC_ExternalTrigConv_T6_TRGO ((uint32_t)(ADC_CFGR1_EXTSEL_0 | ADC_CFGR1_EXTSEL_1)) //3
+
+/* IO Trig */
+#define ADC_ExternalTrigConv_IO_TRGO ((uint32_t)(ADC_CFGR1_EXTSEL_0 | ADC_CFGR1_EXTSEL_1)| ADC_CFGR1_EXTSEL_2) //7
+
+#define IS_ADC_EXTERNAL_TRIG_CONV(CONV) (((CONV) == ADC_ExternalTrigConv_T1_TRGO) || \
+ ((CONV) == ADC_ExternalTrigConv_T1_CC4) || \
+ ((CONV) == ADC_ExternalTrigConv_T1_CC1) || \
+ ((CONV) == ADC_ExternalTrigConv_T1_CC2) || \
+ ((CONV) == ADC_ExternalTrigConv_T1_CC3) || \
+ ((CONV) == ADC_ExternalTrigConv_T2_TRGO) || \
+ ((CONV) == ADC_ExternalTrigConv_T6_TRGO) || \
+ ((CONV) == ADC_ExternalTrigConv_IO_TRGO))
+/**
+ * @}
+ */
+
+/** @defgroup ADC_data_align
+ * @{
+ */
+
+#define ADC_DataAlign_Right ((uint32_t)0x00000000)
+#define ADC_DataAlign_Left ADC_CFGR1_ALIGN
+
+#define IS_ADC_DATA_ALIGN(ALIGN) (((ALIGN) == ADC_DataAlign_Right) || \
+ ((ALIGN) == ADC_DataAlign_Left))
+/**
+ * @}
+ */
+
+/** @defgroup ADC_Scan_Direction
+ * @{
+ */
+
+#define ADC_ScanDirection_Upward ((uint32_t)0x00000000)
+#define ADC_ScanDirection_Backward ADC_CFGR1_SCANDIR
+
+#define IS_ADC_SCAN_DIRECTION(DIRECTION) (((DIRECTION) == ADC_ScanDirection_Upward) || \
+ ((DIRECTION) == ADC_ScanDirection_Backward))
+/**
+ * @}
+ */
+
+/** @defgroup ADC_analog_watchdog_selection
+ * @{
+ */
+
+#define ADC_AnalogWatchdog_Channel_0 ((uint32_t)0x00000000)
+#define ADC_AnalogWatchdog_Channel_1 ((uint32_t)0x04000000)
+#define ADC_AnalogWatchdog_Channel_2 ((uint32_t)0x08000000)
+#define ADC_AnalogWatchdog_Channel_3 ((uint32_t)0x0C000000)
+#define ADC_AnalogWatchdog_Channel_4 ((uint32_t)0x10000000)
+#define ADC_AnalogWatchdog_Channel_5 ((uint32_t)0x14000000)
+
+
+#define IS_ADC_ANALOG_WATCHDOG_CHANNEL(CHANNEL) (((CHANNEL) == ADC_AnalogWatchdog_Channel_0) || \
+ ((CHANNEL) == ADC_AnalogWatchdog_Channel_1) || \
+ ((CHANNEL) == ADC_AnalogWatchdog_Channel_2) || \
+ ((CHANNEL) == ADC_AnalogWatchdog_Channel_3) || \
+ ((CHANNEL) == ADC_AnalogWatchdog_Channel_4) || \
+ ((CHANNEL) == ADC_AnalogWatchdog_Channel_5))
+/**
+ * @}
+ */
+
+/** @defgroup ADC_sampling_times
+ * @{
+ */
+
+#define ADC_SampleTime_1_5Cycles ((uint32_t)0x00000000)
+#define ADC_SampleTime_7_5Cycles ((uint32_t)0x00000001)
+#define ADC_SampleTime_13_5Cycles ((uint32_t)0x00000002)
+#define ADC_SampleTime_28_5Cycles ((uint32_t)0x00000003)
+#define ADC_SampleTime_41_5Cycles ((uint32_t)0x00000004)
+#define ADC_SampleTime_55_5Cycles ((uint32_t)0x00000005)
+#define ADC_SampleTime_71_5Cycles ((uint32_t)0x00000006)
+#define ADC_SampleTime_239_5Cycles ((uint32_t)0x00000007)
+
+#define IS_ADC_SAMPLE_TIME(TIME) (((TIME) == ADC_SampleTime_1_5Cycles) || \
+ ((TIME) == ADC_SampleTime_7_5Cycles) || \
+ ((TIME) == ADC_SampleTime_13_5Cycles) || \
+ ((TIME) == ADC_SampleTime_28_5Cycles) || \
+ ((TIME) == ADC_SampleTime_41_5Cycles) || \
+ ((TIME) == ADC_SampleTime_55_5Cycles) || \
+ ((TIME) == ADC_SampleTime_71_5Cycles) || \
+ ((TIME) == ADC_SampleTime_239_5Cycles))
+/**
+ * @}
+ */
+
+/** @defgroup ADC_thresholds
+ * @{
+ */
+
+#define IS_ADC_THRESHOLD(THRESHOLD) ((THRESHOLD) <= 0xFFF)
+
+/**
+ * @}
+ */
+
+/** @defgroup ADC_channels
+ * @{
+ */
+
+#define ADC_Channel_0 ADC_CHSELR_CHSEL0
+#define ADC_Channel_1 ADC_CHSELR_CHSEL1
+#define ADC_Channel_2 ADC_CHSELR_CHSEL2
+#define ADC_Channel_3 ADC_CHSELR_CHSEL3
+#define ADC_Channel_4 ADC_CHSELR_CHSEL4
+#define ADC_Channel_5 ADC_CHSELR_CHSEL5
+
+#define ADC_Channel_Vrefint ((uint32_t)ADC_Channel_5)
+
+#define IS_ADC_CHANNEL(CHANNEL) (((CHANNEL) != (uint32_t)RESET) && (((CHANNEL) & 0xFFFFFFC0) == (uint32_t)RESET))
+
+/**
+ * @}
+ */
+
+/** @defgroup ADC_interrupts_definition
+ * @{
+ */
+
+#define ADC_IT_ADRDY ADC_IER_ADRDYIE
+#define ADC_IT_EOSMP ADC_IER_EOSMPIE
+#define ADC_IT_EOC ADC_IER_EOCIE
+#define ADC_IT_EOSEQ ADC_IER_EOSEQIE
+#define ADC_IT_OVR ADC_IER_OVRIE
+#define ADC_IT_AWD ADC_IER_AWDIE
+
+#define IS_ADC_CONFIG_IT(IT) (((IT) != (uint32_t)RESET) && (((IT) & 0xFFFFFF60) == (uint32_t)RESET))
+
+#define IS_ADC_GET_IT(IT) (((IT) == ADC_IT_ADRDY) || ((IT) == ADC_IT_EOSMP) || \
+ ((IT) == ADC_IT_EOC) || ((IT) == ADC_IT_EOSEQ) || \
+ ((IT) == ADC_IT_OVR) || ((IT) == ADC_IT_AWD))
+
+#define IS_ADC_CLEAR_IT(IT) (((IT) != (uint32_t)RESET) && (((IT) & 0xFFFFFF60) == (uint32_t)RESET))
+
+/**
+ * @}
+ */
+
+/** @defgroup ADC_flags_definition
+ * @{
+ */
+
+#define ADC_FLAG_ADRDY ADC_ISR_ADRDY
+#define ADC_FLAG_EOSMP ADC_ISR_EOSMP
+#define ADC_FLAG_EOC ADC_ISR_EOC
+#define ADC_FLAG_EOSEQ ADC_ISR_EOSEQ
+#define ADC_FLAG_OVR ADC_ISR_OVR
+#define ADC_FLAG_AWD ADC_ISR_AWD
+
+#define ADC_FLAG_ADEN ((uint32_t)0x01000001)
+#define ADC_FLAG_ADDIS ((uint32_t)0x01000002)
+#define ADC_FLAG_ADSTART ((uint32_t)0x01000004)
+#define ADC_FLAG_ADSTP ((uint32_t)0x01000010)
+#define ADC_FLAG_ADCAL ((uint32_t)0x81000000)
+
+#define IS_ADC_CLEAR_FLAG(FLAG) (((FLAG) != (uint32_t)RESET) && (((FLAG) & 0xFFFFFF60) == (uint32_t)RESET))
+
+#define IS_ADC_GET_FLAG(FLAG) (((FLAG) == ADC_FLAG_ADRDY) || ((FLAG) == ADC_FLAG_EOSMP) || \
+ ((FLAG) == ADC_FLAG_EOC) || ((FLAG) == ADC_FLAG_EOSEQ) || \
+ ((FLAG) == ADC_FLAG_AWD) || ((FLAG) == ADC_FLAG_OVR) || \
+ ((FLAG) == ADC_FLAG_ADEN) || ((FLAG) == ADC_FLAG_ADDIS) || \
+ ((FLAG) == ADC_FLAG_ADSTART) || ((FLAG) == ADC_FLAG_ADSTP) || \
+ ((FLAG) == ADC_FLAG_ADCAL))
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+
+/* Function used to set the ADC configuration to the default reset state *****/
+void ADC_DeInit(ADC_TypeDef* ADCx);
+
+/* Initialization and Configuration functions *********************************/
+void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);
+void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct);
+void ADC_ClockModeConfig(ADC_TypeDef* ADCx, uint32_t ADC_ClockMode);
+void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);
+/* This Function is obsolete and maintained for legacy purpose only.
+ ADC_ClockModeConfig() function should be used instead */
+void ADC_JitterCmd(ADC_TypeDef* ADCx, uint32_t ADC_JitterOff, FunctionalState NewState);
+
+/* Power saving functions *****************************************************/
+void ADC_AutoPowerOffCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
+void ADC_WaitModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
+
+/* Analog Watchdog configuration functions ************************************/
+void ADC_AnalogWatchdogCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
+void ADC_AnalogWatchdogThresholdsConfig(ADC_TypeDef* ADCx, uint16_t HighThreshold,uint16_t LowThreshold);
+void ADC_AnalogWatchdogSingleChannelConfig(ADC_TypeDef* ADCx, uint32_t ADC_AnalogWatchdog_Channel);
+void ADC_AnalogWatchdogSingleChannelCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
+
+/* Temperature Sensor , Vrefint and Vbat management function ******************/
+void ADC_VrefintCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
+
+/* Channels Configuration functions *******************************************/
+void ADC_ChannelConfig(ADC_TypeDef* ADCx, uint32_t ADC_Channel, uint32_t ADC_SampleTime);
+void ADC_ContinuousModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
+void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
+void ADC_OverrunModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
+uint32_t ADC_GetCalibrationFactor(ADC_TypeDef* ADCx);
+void ADC_StopOfConversion(ADC_TypeDef* ADCx);
+void ADC_StartOfConversion(ADC_TypeDef* ADCx);
+uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx);
+
+
+/* Interrupts and flags management functions **********************************/
+void ADC_ITConfig(ADC_TypeDef* ADCx, uint32_t ADC_IT, FunctionalState NewState);
+FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint32_t ADC_FLAG);
+void ADC_ClearFlag(ADC_TypeDef* ADCx, uint32_t ADC_FLAG);
+ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint32_t ADC_IT);
+void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint32_t ADC_IT);
+
+void ADC_AWDWakeup_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);
+void ADC_Diff_Func(ADC_TypeDef* ADCx, FunctionalState NewState);
+void ADC_InterDelay_Func(ADC_TypeDef* ADCx, FunctionalState NewState);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__HK32F030M_ADC_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_awu.h b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_awu.h
new file mode 100644
index 0000000..a6e75c0
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_awu.h
@@ -0,0 +1,59 @@
+/**
+ ******************************************************************************
+ * @file hk32f030m_awu.h
+ * @author Rakan.zhang
+ * @version V1.0
+ * @brief This file contains all functions prototype and macros for the AWU peripheral.
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __HK32F030M_AWU_H
+#define __HK32F030M_AWU_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "hk32f030m.h"
+
+
+
+/* Exported macros ------------------------------------------------------------*/
+
+/* Private macros ------------------------------------------------------------*/
+
+/** @addtogroup AWU_Private_Macros
+ * @{
+ */
+
+
+#define AWU_CR_RESET_VALUE 0x00000000U
+#define AWU_SR_RESET_VALUE 0x00000000U
+#define AWU_SR_BUSY 0x00000001U
+
+typedef enum
+{
+ AWU_CLK_LSI128,
+ AWU_CLK_HSE,
+}AWU_CLK_TYPE;
+
+#define IS_AWU_CLK(AWU_CLK) \
+ (((AWU_CLK) == AWU_CLK_LSI128) || \
+ ((AWU_CLK) == AWU_CLK_HSE))
+/**
+ * @}
+ */
+
+/* Exported functions ------------------------------------------------------- */
+
+/** @addtogroup AWU_Exported_Functions
+ * @{
+ */
+void AWU_DeInit(void);
+void AWU_CLKConfig(AWU_CLK_TYPE eAWU_CLK);
+ErrorStatus AWU_TimerCounterAndStart(uint32_t TimerCounter);
+FlagStatus AWU_GetFlagStatus(void);
+/**
+ * @}
+ */
+
+#endif /* __HK32F030M_AWU_H */
+
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_beep.h b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_beep.h
new file mode 100644
index 0000000..94bafe1
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_beep.h
@@ -0,0 +1,74 @@
+/**
+ ******************************************************************************
+ * @file hk32f030m_beep.h
+ * @author Rakan.Z/Wing.W
+ * @version V1.0
+ * @brief This file contains all functions prototype and macros for the BEEP peripheral.
+ ******************************************************************************
+ */
+
+
+#ifndef __HK32F030M_BEEP_H
+#define __HK32F030M_BEEP_H
+
+#ifdef __cplusplus
+ extern "C"{
+#endif
+
+#include "hk32f030m.h"
+
+typedef struct
+{
+ uint8_t BEEP_Prescaler;
+ uint8_t BEEP_Clock;
+ uint8_t BEEP_TRGOPrescaler;
+ FunctionalState BEEP_TRGOCmd;
+}BEEP_InitTypeDef;
+
+#define BEEP_BUSY_FLAG ((uint32_t)0x80000000U)
+#define BEEP_CFGR_Value ((uint32_t)0x0000000AU)
+#define BEEP_CR_Value ((uint32_t)0x00000003U)
+#define BEEP_CR_BEEP_Mask ((uint32_t)0xFFFFFFF9U)
+#define BEEP_CR_TRGO_Mask ((uint32_t)0xFFFFFFE7U)
+
+#define BEEP_Prescaler_16 ((uint32_t)0x00000006U)
+#define BEEP_Prescaler_32 ((uint32_t)0x00000004U)
+#define BEEP_Prescaler_64 ((uint32_t)0x00000002U)
+#define BEEP_Prescaler_128 ((uint32_t)0x00000000U)
+#define IS_BEEP_PRESCALER(PRESCALER) (((PRESCALER)==BEEP_Prescaler_16) ||\
+ ((PRESCALER)==BEEP_Prescaler_32) ||\
+ ((PRESCALER)==BEEP_Prescaler_64) ||\
+ ((PRESCALER)==BEEP_Prescaler_128))
+
+
+#define BEEP_CLOCK_HSE ((uint32_t)0x00000001U)
+#define BEEP_CLOCK_LSI ((uint32_t)0x00000000U)
+
+#define IS_BEEP_CLOCK(CLOCK) ((CLOCK==(BEEP_CLOCK_HSE))||\
+ CLOCK==(BEEP_CLOCK_LSI))
+
+
+#define BEEP_TRGO_Prescaler_32 ((uint32_t)0x00000010U)
+#define BEEP_TRGO_Prescaler_64 ((uint32_t)0x00000008U)
+#define BEEP_TRGO_Prescaler_128 ((uint32_t)0x00000000U)
+#define IS_BEEP_TRGO_PRESCALER(PRESCALER) (((PRESCALER)==BEEP_TRGO_Prescaler_32) ||\
+ ((PRESCALER)==BEEP_TRGO_Prescaler_64) ||\
+ ((PRESCALER)==BEEP_TRGO_Prescaler_128))
+
+
+
+void BEEP_DeInit(void);
+void BEEP_Init(BEEP_InitTypeDef * BEEP_InitStruct);
+void BEEP_Cmd(FunctionalState NewState);
+void BEEP_ClockSelect(uint8_t BEEP_CLOCK);
+void BEEP_SetPrescaler(uint8_t BEEP_Prescaler);
+void BEEP_SetTRGOPrescaler(uint8_t BEEP_TGRO_Prescaler);
+FlagStatus BEEP_ReadBeepStatus(void);
+void BEEP_TRGOCmd(FunctionalState NewState);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_conf_Template.h b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_conf_Template.h
new file mode 100644
index 0000000..1a8da24
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_conf_Template.h
@@ -0,0 +1,135 @@
+/**
+ ******************************************************************************
+ * @file hk32f030m_conf_Template.h
+ * @brief hk32f030m configuration file of backup.
+ ******************************************************************************
+ * @attention
+ * Users can refer to this file for custom configuration
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __HK32F030M_CONF_H
+#define __HK32F030M_CONF_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+
+/* ########################## HSE/HSI Values adaptation ##################### */
+/**
+ * @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
+ * This value is used by the RCC module to compute the system frequency
+ * (when HSE is used as system clock source, directly or through the PLL).
+ */
+
+
+#define EXTCLK_VALUE ((uint32_t)32000000) /*!< Value of the Internal oscillator in Hz*/
+
+
+
+/**
+ * @brief Internal High Speed oscillator (HSI) value.
+ * This value is used by the RCC module to compute the system frequency
+ * (when HSI is used as system clock source, directly or through the PLL).
+ */
+
+#define HSI_VALUE ((uint32_t)32000000) /*!< Value of the Internal oscillator in Hz*/
+
+
+/**
+ * @brief In the following line adjust the Internal High Speed oscillator (HSI) Startup
+ * Timeout value
+ */
+
+ #define STARTUP_TIMEOUT ((uint32_t)0xFFFF) /*!< Time out for start up */
+
+
+/**
+ * @brief Internal Low Speed oscillator (LSI) value.
+ */
+
+ #define LSI_VALUE ((uint32_t)114000)
+ /*!< Value of the Internal Low Speed oscillator in Hz
+ The real value may vary depending on the variations*/
+
+
+
+
+
+/* Includes ------------------------------------------------------------------*/
+/**
+ * @brief Include module's header file
+ */
+
+ #include "hk32f030m_rcc.h"
+
+ #include "hk32f030m_crc.h"
+
+ #include "hk32f030m_exti.h"
+
+ #include "hk32f030m_flash.h"
+
+ #include "hk32f030m_gpio.h"
+
+ #include "hk32f030m_misc.h"
+
+ #include "hk32f030m_adc.h"
+
+ #include "hk32f030m_syscfg.h"
+
+ #include "hk32f030m_def.h"
+
+ #include "hk32f030m_i2c.h"
+
+ #include "hk32f030m_iwdg.h"
+
+ #include "hk32f030m_pwr.h"
+
+ #include "hk32f030m_spi.h"
+
+ #include "hk32f030m_tim.h"
+
+ #include "hk32f030m_usart.h"
+
+ #include "hk32f030m_iwdg.h"
+
+ #include "hk32f030m_wwdg.h"
+
+ #include "hk32f030m_awu.h"
+
+ #include "hk32f030m_beep.h"
+/* Exported macro ------------------------------------------------------------*/
+
+/* ########################## Assert Selection ############################## */
+/**
+ * @brief Uncomment the line below to expanse the "assert_param" macro in the
+ * drivers code
+ */
+//#define USE_FULL_ASSERT (1U)
+
+#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((char *)__FILE__, __LINE__))
+/* Exported functions ------------------------------------------------------- */
+ void assert_failed(char* file, uint32_t line);
+#else
+ #define assert_param(expr) ((void)0U)
+#endif /* USE_FULL_ASSERT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __HK32F030M_CONF_H */
+
+/************************ (C) COPYRIGHT MKMcircoChuip *****END OF FILE****/
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_crc.h b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_crc.h
new file mode 100644
index 0000000..b3254a3
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_crc.h
@@ -0,0 +1,74 @@
+/**
+ ******************************************************************************
+ * @file hk32f030m_crc.h
+ * @author Thomas.W
+ * @version V1.0
+ * @brief Header file of CRC module
+ * @changelist
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __HK32F030M_CRC_H
+#define __HK32F030M_CRC_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/*!< Includes ----------------------------------------------------------------*/
+#include "hk32f030m.h"
+
+/** @defgroup CRC_ReverseInputData
+ * @{
+ */
+#define CRC_ReverseInputData_No ((uint32_t)0x00000000) /*!< No reverse operation of Input Data */
+#define CRC_ReverseInputData_8bits CRC_CR_REV_IN_0 /*!< Reverse operation of Input Data on 8 bits */
+#define CRC_ReverseInputData_16bits CRC_CR_REV_IN_1 /*!< Reverse operation of Input Data on 16 bits */
+#define CRC_ReverseInputData_32bits CRC_CR_REV_IN /*!< Reverse operation of Input Data on 32 bits */
+
+#define IS_CRC_REVERSE_INPUT_DATA(DATA) (((DATA) == CRC_ReverseInputData_No) || \
+ ((DATA) == CRC_ReverseInputData_8bits) || \
+ ((DATA) == CRC_ReverseInputData_16bits) || \
+ ((DATA) == CRC_ReverseInputData_32bits))
+
+/** @defgroup CRC_PolynomialSize
+ * @brief
+ * @{
+ */
+#define CRC_PolSize_7 CRC_CR_POLSIZE /*!< 7-bit polynomial for CRC calculation */
+#define CRC_PolSize_8 CRC_CR_POLSIZE_1 /*!< 8-bit polynomial for CRC calculation */
+#define CRC_PolSize_16 CRC_CR_POLSIZE_0 /*!< 16-bit polynomial for CRC calculation */
+#define CRC_PolSize_32 ((uint32_t)0x00000000)/*!< 32-bit polynomial for CRC calculation */
+
+#define IS_CRC_POL_SIZE(SIZE) (((SIZE) == CRC_PolSize_7) || \
+ ((SIZE) == CRC_PolSize_8) || \
+ ((SIZE) == CRC_PolSize_16) || \
+ ((SIZE) == CRC_PolSize_32))
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+/* Configuration of the CRC computation unit **********************************/
+void CRC_DeInit(void);
+void CRC_ResetDR(void);
+void CRC_ReverseInputDataSelect(uint32_t CRC_ReverseInputData);
+void CRC_ReverseOutputDataCmd(FunctionalState NewState);
+void CRC_SetInitRegister(uint32_t CRC_InitValue);
+
+/* CRC computation ************************************************************/
+uint32_t CRC_CalcCRC(uint32_t CRC_Data);
+uint32_t CRC_CalcBlockCRC(uint32_t pBuffer[], uint32_t BufferLength);
+uint32_t CRC_GetCRC(void);
+
+/* Independent register (IDR) access (write/read) *****************************/
+void CRC_SetIDRegister(uint8_t CRC_IDValue);
+uint8_t CRC_GetIDRegister(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __HK32F030M_CRC_H */
+
+
+
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_dbgmcu.h b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_dbgmcu.h
new file mode 100644
index 0000000..b6717e8
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_dbgmcu.h
@@ -0,0 +1,55 @@
+/**
+ ******************************************************************************
+ * @file hk32f030m_dbgmcu.h
+ * @author Felix.z
+ * @version V1.0
+ * @brief API file of DBGMCU module
+ * @changelist
+ *
+ ******************************************************************************
+ */
+
+#ifndef __HK32F030M_DBGMCU_H
+#define __HK32F030M_DBGMCU_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "hk32f030m.h"
+
+/** @defgroup DBGMCU_Exported_Constants
+ * @{
+ */
+
+#define DBGMCU_STOP DBGMCU_CR_DBG_STOP
+#define IS_DBGMCU_PERIPH(PERIPH) ((((PERIPH) & 0xFFFFFFF9) == 0x00) && ((PERIPH) != 0x00))
+
+#define DBGMCU_TIM1_STOP DBGMCU_APB1_FZ_DBG_TIM1_STOP
+#define DBGMCU_TIM2_STOP DBGMCU_APB1_FZ_DBG_TIM2_STOP
+#define DBGMCU_TIM6_STOP DBGMCU_APB1_FZ_DBG_TIM6_STOP
+#define DBGMCU_WWDG_STOP DBGMCU_APB1_FZ_DBG_WWDG_STOP
+#define DBGMCU_IWDG_STOP DBGMCU_APB1_FZ_DBG_IWDG_STOP
+#define DBGMCU_I2C1_SMBUS_TIMEOUT DBGMCU_APB1_FZ_DBG_I2C1_SMBUS_TIMEOUT
+#define IS_DBGMCU_APB1PERIPH(PERIPH) ((((PERIPH) & 0xFDDFE2CC) == 0x00) && ((PERIPH) != 0x00))
+
+
+/**
+ * @}
+ */
+
+/* Device and Revision ID management functions ********************************/
+uint32_t DBGMCU_GetREVID(void);
+uint32_t DBGMCU_GetDEVID(void);
+
+/* Peripherals Configuration functions ****************************************/
+void DBGMCU_Config(uint32_t DBGMCU_Periph, FunctionalState NewState);
+void DBGMCU_APB1PeriphConfig(uint32_t DBGMCU_Periph, FunctionalState NewState);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __HK32F030M_DBGMCU_H */
+
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_def.h b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_def.h
new file mode 100644
index 0000000..639f43c
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_def.h
@@ -0,0 +1,111 @@
+/**
+ ******************************************************************************
+ * @file hk32f030m_def.h
+ * @author Rakan.Z
+ * @version V1.0
+ * @changelist
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __HK32F030M_DEF_H
+#define __HK32F030M_DEF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "hk32f030m.h"
+#include
+#define UNUSED(X) (void)X /* To avoid gcc/g++ warnings */
+
+
+#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 /* ___HK32F030M_DEF_H */
+
+
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_exti.h b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_exti.h
new file mode 100644
index 0000000..b3e11a6
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_exti.h
@@ -0,0 +1,107 @@
+/**
+ ******************************************************************************
+ * @file hk32f030m_exti.h
+ * @author Rakan.zhang
+ * @version V1.0
+ * @brief Header file of EXTI module
+ * This file contains all the functions prototypes for the EXTI firmware library
+ * @changelist
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __HK32F030M_EXTI_H
+#define __HK32F030M_EXTI_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "hk32f030m.h"
+
+typedef enum
+{
+ EXTI_Mode_Interrupt = 0x00,
+ EXTI_Mode_Event = 0x04
+}EXTIMode_TypeDef;
+
+#define IS_EXTI_MODE(MODE) (((MODE) == EXTI_Mode_Interrupt) || ((MODE) == EXTI_Mode_Event))
+
+/**
+ * @brief EXTI Trigger enumeration
+ */
+
+typedef enum
+{
+ EXTI_Trigger_Rising = 0x08,
+ EXTI_Trigger_Falling = 0x0C,
+ EXTI_Trigger_Rising_Falling = 0x10
+}EXTITrigger_TypeDef;
+
+#define IS_EXTI_TRIGGER(TRIGGER) (((TRIGGER) == EXTI_Trigger_Rising) || \
+ ((TRIGGER) == EXTI_Trigger_Falling) || \
+ ((TRIGGER) == EXTI_Trigger_Rising_Falling))
+/**
+ * @brief EXTI Init Structure definition
+ */
+
+typedef struct
+{
+ uint32_t EXTI_Line; /*!< Specifies the EXTI lines to be enabled or disabled.
+ This parameter can be any combination of @ref EXTI_Lines */
+
+ EXTIMode_TypeDef EXTI_Mode; /*!< Specifies the mode for the EXTI lines.
+ This parameter can be a value of @ref EXTIMode_TypeDef */
+
+ EXTITrigger_TypeDef EXTI_Trigger; /*!< Specifies the trigger signal active edge for the EXTI lines.
+ This parameter can be a value of @ref EXTIMode_TypeDef */
+
+ FunctionalState EXTI_LineCmd; /*!< Specifies the new state of the selected EXTI lines.
+ This parameter can be set either to ENABLE or DISABLE */
+}EXTI_InitTypeDef;
+
+/** @defgroup EXTI_Lines
+ * @{
+ */
+
+#define EXTI_Line0 ((uint32_t)0x00001) /*!< External interrupt line 0 */
+#define EXTI_Line1 ((uint32_t)0x00002) /*!< External interrupt line 1 */
+#define EXTI_Line2 ((uint32_t)0x00004) /*!< External interrupt line 2 */
+#define EXTI_Line3 ((uint32_t)0x00008) /*!< External interrupt line 3 */
+#define EXTI_Line4 ((uint32_t)0x00010) /*!< External interrupt line 4 */
+#define EXTI_Line5 ((uint32_t)0x00020) /*!< External interrupt line 5 */
+#define EXTI_Line6 ((uint32_t)0x00040) /*!< External interrupt line 6 */
+#define EXTI_Line7 ((uint32_t)0x00080) /*!< External interrupt line 7 */
+#define EXTI_Line8 ((uint32_t)0x00100) /*!< External interrupt line 8 Connected to the ADC AWD event */
+#define EXTI_Line9 ((uint32_t)0x00200) /*!< External interrupt line 9 Connected to the USART wakeup event */
+#define EXTI_Line10 ((uint32_t)0x00400) /*!< External interrupt line 10 Connected to the IIC wakeup event */
+#define EXTI_Line11 ((uint32_t)0x00800) /*!< External interrupt line 11 Connected to the AWU Wakeup event */
+
+
+
+#define IS_EXTI_LINE(LINE) ((((LINE) & (uint32_t)0xFFFFF000) == 0x00) && ((LINE) != (uint16_t)0x00))
+#define IS_GET_EXTI_LINE(LINE) (((LINE) == EXTI_Line0) || ((LINE) == EXTI_Line1) || \
+ ((LINE) == EXTI_Line2) || ((LINE) == EXTI_Line3) || \
+ ((LINE) == EXTI_Line4) || ((LINE) == EXTI_Line5) || \
+ ((LINE) == EXTI_Line6) || ((LINE) == EXTI_Line7) || \
+ ((LINE) == EXTI_Line8) || ((LINE) == EXTI_Line9) || \
+ ((LINE) == EXTI_Line10) || ((LINE) == EXTI_Line11) )
+/** @defgroup EXTI_Exported_Functions
+ * @{
+ */
+
+void EXTI_DeInit(void);
+void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);
+void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct);
+void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line);
+FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line);
+ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);
+void EXTI_ClearFlag(uint32_t EXTI_Line);
+void EXTI_ClearITPendingBit(uint32_t EXTI_Line);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_flash.h b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_flash.h
new file mode 100644
index 0000000..b8e921e
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_flash.h
@@ -0,0 +1,261 @@
+/**
+ ******************************************************************************
+ * @file hk32f030m_flash.h
+ * @author Rakan.Z/laura.C
+ * @version V1.0
+ * @brief API file of flash module
+ * @changelist
+ ******************************************************************************
+ */
+
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __HK32F030M_FLASH_H
+#define __HK32F030M_FLASH_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "hk32f030m.h"
+
+
+/* Exported types ------------------------------------------------------------*/
+
+/** FLASH Status */
+typedef enum
+{
+ FLASH_BUSY = 1,
+ FLASH_ERROR_WRP,
+ FLASH_ERROR_PROGRAM,
+ FLASH_COMPLETE,
+ FLASH_TIMEOUT
+}FLASH_Status;
+
+/* Exported constants --------------------------------------------------------*/
+
+
+/** FLASH_Latency */
+#define FLASH_Latency_0 ((uint32_t)0x00000000) /*HCLK=16Mhz*/
+#define FLASH_Latency_1 ((uint32_t)0x00000001) /*16Mhz= 0x08000000) && ((ADDRESS) <= 0x08003FFF))
+
+#define FLASH_OB_RDP_ADDRESS 0x1FFFF800
+#define FLASH_OB_USER_ADDRESS 0x1FFFF802
+#define FLASH_OB_DATA0_ADDRESS 0x1FFFF804
+#define FLASH_OB_DATA1_ADDRESS 0x1FFFF806
+#define FLASH_OB_WRP_ADDRESS 0x1FFFF808
+#define FLASH_OB_IWDG_ADDRESS 0x1FFFF810
+#define FLASH_OB_LSI_LP_ADDRESS 0x1FFFF814
+#define FLASH_OB_DBG_CLK_ADDRESS 0x1FFFF816
+
+/* EEPROM_Address 16K devices */
+#define IS_EEPROM_PROGRAM_ADDRESS(ADDRESS) (((ADDRESS) >= 0x0C000000) && ((ADDRESS) <= 0x0C0001C0))
+
+/** FLASH_Option_Bytes_Write_Protection */
+#define OB_WRP_Pages0to3 ((uint32_t)0x00000001) /* Write protection of page 0 to 3 */
+#define OB_WRP_Pages4to7 ((uint32_t)0x00000002) /* Write protection of page 4 to 7 */
+#define OB_WRP_Pages8to11 ((uint32_t)0x00000004) /* Write protection of page 8 to 11 */
+#define OB_WRP_Pages12to15 ((uint32_t)0x00000008) /* Write protection of page 12 to 15 */
+#define OB_WRP_Pages16to19 ((uint32_t)0x00000010) /* Write protection of page 16 to 19 */
+#define OB_WRP_Pages20to23 ((uint32_t)0x00000020) /* Write protection of page 20 to 23 */
+#define OB_WRP_Pages24to27 ((uint32_t)0x00000040) /* Write protection of page 24 to 27 */
+#define OB_WRP_Pages28to31 ((uint32_t)0x00000080) /* Write protection of page 28 to 31 */
+#define OB_WRP_Pages32to35 ((uint32_t)0x00000100) /* Write protection of page 32 to 35 */
+#define OB_WRP_Pages36to39 ((uint32_t)0x00000200) /* Write protection of page 36 to 39 */
+#define OB_WRP_Pages40to43 ((uint32_t)0x00000400) /* Write protection of page 40 to 43 */
+#define OB_WRP_Pages44to47 ((uint32_t)0x00000800) /* Write protection of page 44 to 47 */
+#define OB_WRP_Pages48to51 ((uint32_t)0x00001000) /* Write protection of page 48 to 51 */
+#define OB_WRP_Pages52to55 ((uint32_t)0x00002000) /* Write protection of page 52 to 55 */
+#define OB_WRP_Pages56to59 ((uint32_t)0x00004000) /* Write protection of page 56 to 59 */
+#define OB_WRP_Pages60to63 ((uint32_t)0x00008000) /* Write protection of page 60 to 63 */
+#define OB_WRP_Pages64to67 ((uint32_t)0x00010000) /* Write protection of page 64 to 67 */
+#define OB_WRP_Pages68to71 ((uint32_t)0x00020000) /* Write protection of page 68 to 71 */
+#define OB_WRP_Pages72to75 ((uint32_t)0x00040000) /* Write protection of page 72 to 75 */
+#define OB_WRP_Pages76to79 ((uint32_t)0x00080000) /* Write protection of page 76 to 79 */
+#define OB_WRP_Pages80to83 ((uint32_t)0x00100000) /* Write protection of page 80 to 83 */
+#define OB_WRP_Pages84to87 ((uint32_t)0x00200000) /* Write protection of page 84 to 87 */
+#define OB_WRP_Pages88to91 ((uint32_t)0x00400000) /* Write protection of page 88 to 91 */
+#define OB_WRP_Pages92to95 ((uint32_t)0x00800000) /* Write protection of page 92 to 95 */
+#define OB_WRP_Pages96to99 ((uint32_t)0x01000000) /* Write protection of page 96 to 99 */
+#define OB_WRP_Pages100to103 ((uint32_t)0x02000000) /* Write protection of page 100 to 103 */
+#define OB_WRP_Pages104to107 ((uint32_t)0x04000000) /* Write protection of page 104 to 107 */
+#define OB_WRP_Pages108to111 ((uint32_t)0x08000000) /* Write protection of page 108 to 111 */
+#define OB_WRP_Pages112to115 ((uint32_t)0x10000000) /* Write protection of page 112 to 115 */
+#define OB_WRP_Pages116to119 ((uint32_t)0x20000000) /* Write protection of page 116 to 119 */
+#define OB_WRP_Pages120to123 ((uint32_t)0x40000000) /* Write protection of page 120 to 123 */
+#define OB_WRP_Pages124to127 ((uint32_t)0x80000000) /* Write protection of page 124 to 127 */
+
+#define OB_WRP_AllPages ((uint32_t)0xFFFFFFFF) /*!< Write protection of all Sectors */
+#define OB_WRP_None ((uint32_t)0x00000000) /*!< Write protection of none */
+
+
+/** FLASH_Option_Bytes_Read_Protection */
+
+/** FLASH_Read Protection Level */
+#define OB_RDP_Level_0 ((uint8_t)0xAA)
+#define OB_RDP_Level_1 ((uint8_t)0xBB)
+/*#define OB_RDP_Level_2 ((uint8_t)0xCC)*/ /* Warning: When enabling read protection level 2
+ it's no more possible to go back to level 1 or 0 */
+
+#define IS_OB_RDP(LEVEL) (((LEVEL) == OB_RDP_Level_0)||\
+ ((LEVEL) == OB_RDP_Level_1))/*||\
+ ((LEVEL) == OB_RDP_Level_2))*/
+
+/** FLASH_Option_Bytes_IWatchdog */
+
+#define OB_IWDG_SW ((uint8_t)0x01) /*!< Software IWDG selected */
+#define OB_IWDG_HW ((uint8_t)0x00) /*!< Hardware IWDG selected */
+#define IS_OB_IWDG_SOURCE(SOURCE) (((SOURCE) == OB_IWDG_SW) || ((SOURCE) == OB_IWDG_HW))
+
+/**
+ * @}
+ */
+
+/* defgroup FLASH_Option_Bytes_nRST_STOP */
+
+#define OB_STOP_NoRST ((uint8_t)0x02) /*!< No reset generated when entering in STOP */
+#define OB_STOP_RST ((uint8_t)0x00) /*!< Reset generated when entering in STOP */
+#define IS_OB_STOP_SOURCE(SOURCE) (((SOURCE) == OB_STOP_NoRST) || ((SOURCE) == OB_STOP_RST))
+
+/**
+ * @}
+ */
+ /**
+ * @brief Macro used by the assert function in order to check the different
+ * sensitivity values for the option bytes Address
+ */
+
+#define OPTION_BYTE_START_DATA1_ADDRESS ((uint32_t)0x1FFFF804)
+#define OPTION_BYTE_END_DATA1_ADDRESS ((uint32_t)0x1FFFF806)
+
+#define IS_OB_DATA_ADDRESS(ADDRESS) (((ADDRESS) >= OPTION_BYTE_START_DATA1_ADDRESS) && \
+ ((ADDRESS) <= OPTION_BYTE_END_DATA1_ADDRESS))
+
+
+
+/** FLASH_Flags */
+
+#define FLASH_FLAG_BSY FLASH_SR_BSY /*!< FLASH Busy flag */
+#define FLASH_FLAG_WRPERR FLASH_SR_WRPERR /*!< FLASH Write protected error flag */
+#define FLASH_FLAG_EOP FLASH_SR_EOP /*!< FLASH End of Programming flag */
+
+#define IS_FLASH_CLEAR_FLAG(FLAG) ((((FLAG) & (uint32_t)0xFFFFFFCB) == 0x00000000) && ((FLAG) != 0x00000000))
+#define IS_FLASH_GET_FLAG(FLAG) (((FLAG) == FLASH_FLAG_BSY) || ((FLAG) == FLASH_FLAG_WRPERR) || ((FLAG) == FLASH_FLAG_EOP))
+
+/** FLASH_Timeout_definition */
+#define FLASH_ER_PRG_TIMEOUT ((uint32_t)0x000B0000)
+
+
+
+/** FLASH_Legacy */
+#define FLASH_WRProt_Pages0to3 OB_WRP_Pages0to3
+#define FLASH_WRProt_Pages4to7 OB_WRP_Pages4to7
+#define FLASH_WRProt_Pages8to11 OB_WRP_Pages8to11
+#define FLASH_WRProt_Pages12to15 OB_WRP_Pages12to15
+#define FLASH_WRProt_Pages16to19 OB_WRP_Pages16to19
+#define FLASH_WRProt_Pages20to23 OB_WRP_Pages20to23
+#define FLASH_WRProt_Pages24to27 OB_WRP_Pages24to27
+#define FLASH_WRProt_Pages28to31 OB_WRP_Pages28to31
+#define FLASH_WRProt_Pages32to35 OB_WRP_Pages32to35
+#define FLASH_WRProt_Pages36to39 OB_WRP_Pages36to39
+#define FLASH_WRProt_Pages40to43 OB_WRP_Pages40to43
+#define FLASH_WRProt_Pages44to47 OB_WRP_Pages44to47
+#define FLASH_WRProt_Pages48to51 OB_WRP_Pages48to51
+#define FLASH_WRProt_Pages52to55 OB_WRP_Pages52to55
+#define FLASH_WRProt_Pages56to59 OB_WRP_Pages56to59
+#define FLASH_WRProt_Pages60to63 OB_WRP_Pages60to63
+#define FLASH_WRProt_Pages64to67 OB_WRP_Pages64to67
+#define FLASH_WRProt_Pages68to71 OB_WRP_Pages68to71
+#define FLASH_WRProt_Pages72to75 OB_WRP_Pages72to75
+#define FLASH_WRProt_Pages76to79 OB_WRP_Pages76to79
+#define FLASH_WRProt_Pages80to83 OB_WRP_Pages80to83
+#define FLASH_WRProt_Pages84to87 OB_WRP_Pages84to87
+#define FLASH_WRProt_Pages88to91 OB_WRP_Pages88to91
+#define FLASH_WRProt_Pages92to95 OB_WRP_Pages92to95
+#define FLASH_WRProt_Pages96to99 OB_WRP_Pages96to99
+#define FLASH_WRProt_Pages100to103 OB_WRP_Pages100to103
+#define FLASH_WRProt_Pages104to107 OB_WRP_Pages104to107
+#define FLASH_WRProt_Pages108to111 OB_WRP_Pages108to111
+#define FLASH_WRProt_Pages112to115 OB_WRP_Pages112to115
+#define FLASH_WRProt_Pages116to119 OB_WRP_Pages116to119
+#define FLASH_WRProt_Pages120to123 OB_WRP_Pages120to123
+#define FLASH_WRProt_Pages124to127 OB_WRP_Pages124to127
+
+
+#define FLASH_WRProt_AllPages OB_WRP_AllPages
+
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+
+
+/* FLASH Interface configuration functions ************************************/
+void FLASH_SetLatency(uint32_t FLASH_Latency);
+
+
+/* FLASH Memory Programming functions *****************************************/
+void FLASH_Unlock(void);
+void FLASH_Lock(void);
+FLASH_Status FLASH_ErasePage(uint32_t Page_Address);
+FLASH_Status FLASH_EraseAllPages(void);
+FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data);
+FLASH_Status FLASH_ProgramByte(uint32_t Address, uint8_t Data);
+
+/* FLASH Option Bytes Programming functions *****************************************/
+void FLASH_OB_Unlock(void);
+void FLASH_OB_Lock(void);
+FLASH_Status FLASH_OB_EraseByte(uint32_t Address);
+
+FLASH_Status FLASH_OB_WRPConfig(uint32_t OB_WRP);
+FLASH_Status FLASH_OB_RDPConfig(uint8_t OB_RDP);
+FLASH_Status FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP );
+FLASH_Status FLASH_OB_IWDG_RLRConfig(uint16_t OB_IWDG_RLR, FunctionalState NewState);
+FLASH_Status FLASH_OB_LSILPConfig(FunctionalState NewState);
+FLASH_Status FLASH_OB_DBGCLKConfig(FunctionalState NewState);
+FLASH_Status FLASH_OB_WriteUser(uint8_t OB_USER);
+FLASH_Status FLASH_OB_ProgramData(uint32_t Address, uint16_t Data);
+uint8_t FLASH_OB_GetUser(void);
+uint32_t FLASH_OB_GetWRP(void);
+FlagStatus FLASH_OB_GetRDP(void);
+
+/* FLASH Interrupts and flags management functions **********************************/
+void FLASH_ITConfig(uint32_t FLASH_IT, FunctionalState NewState);
+FlagStatus FLASH_GetFlagStatus(uint32_t FLASH_FLAG);
+void FLASH_ClearFlag(uint32_t FLASH_FLAG);
+FLASH_Status FLASH_GetStatus(void);
+FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout);
+
+
+FLASH_Status EEPROM_EraseByte(uint32_t Address);
+FLASH_Status EEPROM_ProgramByte(uint32_t Address, uint8_t Data);
+
+
+void Sys_GetDevice64BitUID(uint32_t *UID);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __HK32F030M_FLASH_H */
+
+
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_gpio.h b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_gpio.h
new file mode 100644
index 0000000..3a3722d
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_gpio.h
@@ -0,0 +1,449 @@
+/**
+ ******************************************************************************
+ * @file hk32f030m_gpio.h
+ * @version V1.0.1
+ * @date 2019-08-15
+ * author Rakan.Z
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __HK32F030M_GPIO_H
+#define __HK32F030M_GPIO_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "hk32f030m.h"
+
+/** @addtogroup GPIO
+ * @{
+ */
+/* Exported types ------------------------------------------------------------*/
+
+#define IS_GPIO_ALL_PERIPH(PERIPH) (((PERIPH) == GPIOA) || \
+ ((PERIPH) == GPIOB) || \
+ ((PERIPH) == GPIOC) || \
+ ((PERIPH) == GPIOD) )
+
+#define IS_GPIO_LIST_PERIPH(PERIPH) (((PERIPH) == GPIOA) || \
+ ((PERIPH) == GPIOB))
+
+/** @defgroup Configuration_Mode_enumeration
+ * @{
+ */
+typedef enum
+{
+ GPIO_Mode_IN = 0x00, /*!< GPIO Input Mode */
+ GPIO_Mode_OUT = 0x01, /*!< GPIO Output Mode */
+ GPIO_Mode_AF = 0x02, /*!< GPIO Alternate function Mode */
+ GPIO_Mode_AN = 0x03 /*!< GPIO Analog In/Out Mode */
+}GPIOMode_TypeDef;
+
+#define IS_GPIO_MODE(MODE) (((MODE) == GPIO_Mode_IN)|| ((MODE) == GPIO_Mode_OUT) || \
+ ((MODE) == GPIO_Mode_AF)|| ((MODE) == GPIO_Mode_AN))
+/**
+ * @}
+ */
+
+/** @defgroup Output_type_enumeration
+ * @{
+ */
+typedef enum
+{
+ GPIO_OType_PP = 0x00,
+ GPIO_OType_OD = 0x01
+}GPIOOType_TypeDef;
+
+#define IS_GPIO_OTYPE(OTYPE) (((OTYPE) == GPIO_OType_PP) || ((OTYPE) == GPIO_OType_OD))
+
+/**
+ * @}
+ */
+
+/** @defgroup Output_Maximum_frequency_enumeration
+ * @{
+ */
+typedef enum
+{
+ GPIO_Speed_Level_1 = 0x00, /*!< I/O output speed: Low 2 MHz */
+ GPIO_Speed_Level_2 = 0x01, /*!< I/O output speed: Medium 10 MHz */
+}GPIOSpeed_TypeDef;
+
+#define IS_GPIO_SPEED(SPEED) (((SPEED) == GPIO_Speed_Level_1) || ((SPEED) == GPIO_Speed_Level_2))
+/**
+ * @}
+ */
+
+/** @defgroup Configuration_Pull-Up_Pull-Down_enumeration
+ * @{
+ */
+typedef enum
+{
+ GPIO_PuPd_NOPULL = 0x00,
+ GPIO_PuPd_UP = 0x01,
+ GPIO_PuPd_DOWN = 0x02
+}GPIOPuPd_TypeDef;
+
+#define IS_GPIO_PUPD(PUPD) (((PUPD) == GPIO_PuPd_NOPULL) || ((PUPD) == GPIO_PuPd_UP) || \
+ ((PUPD) == GPIO_PuPd_DOWN))
+/**
+ * @}
+ */
+
+/** @defgroup Bit_SET_and_Bit_RESET_enumeration
+ * @{
+ */
+typedef enum
+{
+ Bit_RESET = 0,
+ Bit_SET
+}BitAction;
+
+#define IS_GPIO_BIT_ACTION(ACTION) (((ACTION) == Bit_RESET) || ((ACTION) == Bit_SET))
+/**
+ * @}
+ */
+
+/* @brief Configuration Schmit */
+typedef enum
+{
+ GPIO_Schmit_Disable = 0x0,
+ GPIO_Schmit_Enable = 0x1,
+}GPIOSchmit_TypeDef;
+/**
+ * @brief GPIO Init structure definition
+ */
+typedef struct
+{
+ uint32_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured.
+ This parameter can be any value of @ref GPIO_pins_define */
+
+ GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins.
+ This parameter can be a value of @ref GPIOMode_TypeDef */
+
+ GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins.
+ This parameter can be a value of @ref GPIOSpeed_TypeDef */
+
+ GPIOOType_TypeDef GPIO_OType; /*!< Specifies the operating output type for the selected pins.
+ This parameter can be a value of @ref GPIOOType_TypeDef */
+
+ GPIOPuPd_TypeDef GPIO_PuPd; /*!< Specifies the operating Pull-up/Pull down for the selected pins.
+ This parameter can be a value of @ref GPIOPuPd_TypeDef */
+
+ GPIOSchmit_TypeDef GPIO_Schmit; /*!*/
+
+}GPIO_InitTypeDef;
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup GPIO_Exported_Constants
+ * @{
+ */
+
+/** @defgroup 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 IS_GPIO_PIN(PIN) ((PIN) != (uint16_t)0x00)
+
+#define IS_GET_GPIO_PIN(PIN) (((PIN) == GPIO_Pin_0) || \
+ ((PIN) == GPIO_Pin_1) || \
+ ((PIN) == GPIO_Pin_2) || \
+ ((PIN) == GPIO_Pin_3) || \
+ ((PIN) == GPIO_Pin_4) || \
+ ((PIN) == GPIO_Pin_5) || \
+ ((PIN) == GPIO_Pin_6) || \
+ ((PIN) == GPIO_Pin_7) || \
+ ((PIN) == GPIO_Pin_8) || \
+ ((PIN) == GPIO_Pin_9) || \
+ ((PIN) == GPIO_Pin_10) || \
+ ((PIN) == GPIO_Pin_11) || \
+ ((PIN) == GPIO_Pin_12) || \
+ ((PIN) == GPIO_Pin_13) || \
+ ((PIN) == GPIO_Pin_14) || \
+ ((PIN) == GPIO_Pin_15))
+
+/**
+ * @}
+ */
+
+/** @defgroup GPIO_Pin_sources
+ * @{
+ */
+#define GPIO_PinSource0 ((uint8_t)0x00)
+#define GPIO_PinSource1 ((uint8_t)0x01)
+#define GPIO_PinSource2 ((uint8_t)0x02)
+#define GPIO_PinSource3 ((uint8_t)0x03)
+#define GPIO_PinSource4 ((uint8_t)0x04)
+#define GPIO_PinSource5 ((uint8_t)0x05)
+#define GPIO_PinSource6 ((uint8_t)0x06)
+#define GPIO_PinSource7 ((uint8_t)0x07)
+#define GPIO_PinSource8 ((uint8_t)0x08)
+#define GPIO_PinSource9 ((uint8_t)0x09)
+#define GPIO_PinSource10 ((uint8_t)0x0A)
+#define GPIO_PinSource11 ((uint8_t)0x0B)
+#define GPIO_PinSource12 ((uint8_t)0x0C)
+#define GPIO_PinSource13 ((uint8_t)0x0D)
+#define GPIO_PinSource14 ((uint8_t)0x0E)
+#define GPIO_PinSource15 ((uint8_t)0x0F)
+
+#define IS_GPIO_PIN_SOURCE(PINSOURCE) (((PINSOURCE) == GPIO_PinSource0) || \
+ ((PINSOURCE) == GPIO_PinSource1) || \
+ ((PINSOURCE) == GPIO_PinSource2) || \
+ ((PINSOURCE) == GPIO_PinSource3) || \
+ ((PINSOURCE) == GPIO_PinSource4) || \
+ ((PINSOURCE) == GPIO_PinSource5) || \
+ ((PINSOURCE) == GPIO_PinSource6) || \
+ ((PINSOURCE) == GPIO_PinSource7) || \
+ ((PINSOURCE) == GPIO_PinSource8) || \
+ ((PINSOURCE) == GPIO_PinSource9) || \
+ ((PINSOURCE) == GPIO_PinSource10) || \
+ ((PINSOURCE) == GPIO_PinSource11) || \
+ ((PINSOURCE) == GPIO_PinSource12) || \
+ ((PINSOURCE) == GPIO_PinSource13) || \
+ ((PINSOURCE) == GPIO_PinSource14) || \
+ ((PINSOURCE) == GPIO_PinSource15))
+/**
+ * @}
+ */
+
+/** @defgroup GPIO_Alternate_function_selection_define
+ * @{
+ */
+
+/**
+ * @brief AF 0 selection
+ */
+
+#define GPIO_AF_0 ((uint8_t)0x00) /* (I2C1_SWD)I2C1_SMBA, I2C1_SCL, SWCLK_I2C1_SDA, I2C1_SDA, SWDIO*/
+/**
+ * @brief AF 1 selection
+ */
+#define GPIO_AF_1 ((uint8_t)0x01) /* (USART1)USART1_TX, USART1_RX, USART1_CK */
+/**
+ * @brief AF 2 selection
+ */
+#define GPIO_AF_2 ((uint8_t)0x02) /* (SPI)SPI1_SCK, SPI1_NSS, SPI1_MISO, SPI1_NSS, SPI1_MOSI*/
+/**
+ * @brief AF 3 selection
+ */
+#define GPIO_AF_3 ((uint8_t)0x03) /* (TIM1)TIM1_BKIN, TIM1_CH1N, TIM1_CH2N, TIM1_CH3N,TIM1_CH3_CH1N,TIM1_CH4_CH2N, TIM1_ETR,TIM1_CH1,TIM1_CH2,TIM1_CH4,TIM1_ETR */
+
+/**
+ * @brief AF 4 selection
+ */
+#define GPIO_AF_4 ((uint8_t)0x04) /* (TIM2)TIM2_CH3, TIM2_ETR, TIM2_CH4, TIM2_CH2, TIM2_CH1*/
+
+/**
+ * @brief AF 5 selection
+ */
+#define GPIO_AF_5 ((uint8_t)0x05) /* (RCC)RCC_MCO */
+
+/**
+ * @brief AF 6 selection
+ */
+#define GPIO_AF_6 ((uint8_t)0x06) /*(BEEPER)BEEP */
+/**
+ * @brief AF 7 selection
+ */
+#define GPIO_AF_7 ((uint8_t)0x07) /*(ADC1)ADC1_ETR */
+
+#define IS_GPIO_AF(AF) (((AF) == GPIO_AF_0) || ((AF) == GPIO_AF_1) || \
+ ((AF) == GPIO_AF_2) || ((AF) == GPIO_AF_3) || \
+ ((AF) == GPIO_AF_4) || ((AF) == GPIO_AF_5) || \
+ ((AF) == GPIO_AF_6) || ((AF) == GPIO_AF_7) )
+
+
+
+/**
+ * @brief IOMUX PIN selection
+ */
+#define GPIOMUX_AF3_TIM1CH3 ((uint8_t)0x01) /* PC3_AF3_TIM1CH3 */ // PC3 AS AF3
+#define GPIOMUX_AF3_TIM1CH1N ((uint8_t)0x06) /* PC3_AF3_TIM1CH1N */ // PC3 AS AF3
+#define GPIOMUX_AF3_TIM1CH4 ((uint8_t)0x02) /* PC4_AF3_TIM1CH4 */ // PC4 AS AF3
+#define GPIOMUX_AF3_TIM1CH2N ((uint8_t)0x05) /* PC4_AF3_TIM1CH2N */ // PC4 AS AF3
+#define GPIOMUX_AF0_SWCLK ((uint8_t)0x04) /* PB5_AF0_SWCLK */ // PB5 AS AF0
+#define GPIOMUX_AF0_I2C_SDA ((uint8_t)0x03) /* PB5_AF0_I2C_SDA */ // PB5 AS AF0
+
+#define GPIO_IOMUX_AF(IOMUX_AF) (((IOMUX_AF) == GPIOMUX_AF_3_TIM1CH3) || ((IOMUX_AF) == GPIOMUX_AF_3_TIM1CH1N) || \
+ ((IOMUX_AF) == GPIOMUX_AF_3_TIM1CH4) || ((IOMUX_AF) == GPIOMUX_AF_3_TIM1CH2N)|| \
+ ((IOMUX_AF) == GPIOMUX_AF_0_SWCLK)|| ((IOMUX_AF) == GPIOMUX_AF_0_I2C_SDA) )
+
+/**
+ * @}
+ */
+
+/** @defgroup GPIO_Speed_Legacy
+ * @{
+ */
+
+#define GPIO_Speed_2MHz GPIO_Speed_Level_1 /*!< I/O output speed: Low 2 MHz */
+#define GPIO_Speed_10MHz GPIO_Speed_Level_2 /*!< I/O output speed: Medium 10 MHz */
+
+/**
+ * @}
+ */
+
+/** @defgroup GPIO_IOMUX
+ * @{
+ */
+#define IOMUX_PC3_TIM1CH3 0x00000001
+#define IOMUX_PC3_TIM1CH1N 0xFFFFFFFE
+#define IOMUX_PC4_TIM1CH4 0x00000002
+#define IOMUX_PC4_TIM1CH2N 0xFFFFFFFD
+#define IOMUX_PB5_SWCLK 0x00000004
+#define IOMUX_PB5_I2C_SDA 0xFFFFFFFB
+
+
+ /** @defgroup GPIO_IOMUX_function_selection_define
+ * @{
+ */
+typedef enum
+{
+ // SO8N PIN
+ IOMUX_PIN1,
+ //IOMUX_PIN4, only HK32F0301Mxx
+ IOMUX_PIN5,
+ IOMUX_PIN6,
+ IOMUX_PIN7,
+ IOMUX_PIN8,
+ // TSSOP16 PIN
+ IOMUX_PIN9,
+ IOMUX_PIN12,
+ IOMUX_PIN15,
+ // TSSOP20/UFQFN20 PIN
+ IOMUX_PIN2,
+ IOMUX_PIN11
+
+}IOMUX_PIN;
+
+/// list of IOMUX_FuncPin
+
+#define IOMUX_PD6_SEL_PD6 ((uint32_t)0x00000000)
+#define IOMUX_PD6_SEL_PA1 ((uint32_t)0x00000080)
+#define IOMUX_PD6_SEL_PD4 ((uint32_t)0x00000100)
+#define IOMUX_PD6_SEL_PA2 ((uint32_t)0x00000180)
+#define IOMUX_PD6_SEL_MASK ((uint32_t)0xFFFFFE7F)
+
+#define IOMUX_PB5_SEL_PB5 ((uint32_t)0x00000000)
+#define IOMUX_PB5_SEL_PA3 ((uint32_t)0x00000002)
+#define IOMUX_PB5_SEL_PD2 ((uint32_t)0x00000004)
+#define IOMUX_PB5_SEL_MASK ((uint32_t)0xFFFFFFF9)
+
+#define IOMUX_NRST_SEL_NRST ((uint32_t)0x00000002)
+#define IOMUX_NRST_SEL_PA0 ((uint32_t)0x00000000)
+#define IOMUX_NRST_SEL_PB4 ((uint32_t)0x00000001)
+#define IOMUX_NRST_SEL_MASK ((uint32_t)0xFFFFFFFE)
+
+#define IOMUX_PC4_SEL_PC4 ((uint32_t)0x00000000)
+#define IOMUX_PC4_SEL_PC5 ((uint32_t)0x00000008)
+#define IOMUX_PC4_SEL_PC3 ((uint32_t)0x00000010)
+#define IOMUX_PC4_SEL_PC7 ((uint32_t)0x00000018)
+#define IOMUX_PC4_SEL_MASK ((uint32_t)0xFFFFFFE7)
+
+#define IOMUX_PD5_SEL_PD5 ((uint32_t)0x00000000)
+#define IOMUX_PD5_SEL_PD3 ((uint32_t)0x00000020)
+#define IOMUX_PD5_SEL_PD1 ((uint32_t)0x00000040)
+#define IOMUX_PD5_SEL_PC6 ((uint32_t)0x00000060)
+#define IOMUX_PD5_SEL_MASK ((uint32_t)0xFFFFFF9F)
+
+#define NRST_PINKEY (uint32_t)(0x00005AE1)
+
+#define IS_IOMUX_PIN(IOMUX_PIN) (((IOMUX_PIN) == IOMUX_PIN1) ||((IOMUX_PIN) == IOMUX_PIN2) ||\
+ ((IOMUX_PIN) == IOMUX_PIN5) || ((IOMUX_PIN) == IOMUX_PIN6) ||\
+ ((IOMUX_PIN) == IOMUX_PIN7) || ((IOMUX_PIN) == IOMUX_PIN8) ||\
+ ((IOMUX_PIN) == IOMUX_PIN9) || ((IOMUX_PIN) == IOMUX_PIN11)||\
+ ((IOMUX_PIN) == IOMUX_PIN12) || ((IOMUX_PIN) == IOMUX_PIN15) )
+
+
+#define IS_IOMUX_PINFNC(IOMUX_PINFNC) (((IOMUX_PINFNC) == IOMUX_PD6_SEL_PD6) || ((IOMUX_PINFNC) == IOMUX_PD6_SEL_PA1) || \
+ ((IOMUX_PINFNC) == IOMUX_PD6_SEL_PD4) || ((IOMUX_PINFNC) == IOMUX_PD6_SEL_PA2) || \
+ ((IOMUX_PINFNC) == IOMUX_PD6_SEL_MASK) || ((IOMUX_PINFNC) == IOMUX_PB5_SEL_PB5) || \
+ ((IOMUX_PINFNC) == IOMUX_PB5_SEL_PA3) || ((IOMUX_PINFNC) == IOMUX_PB5_SEL_PD2) || \
+ ((IOMUX_PINFNC) == IOMUX_PB5_SEL_MASK) || ((IOMUX_PINFNC) == IOMUX_NRST_SEL_NRST) || \
+ ((IOMUX_PINFNC) == IOMUX_NRST_SEL_PB4) || ((IOMUX_PINFNC) == IOMUX_NRST_SEL_MASK) || \
+ ((IOMUX_PINFNC) == IOMUX_PC4_SEL_PC4) || ((IOMUX_PINFNC) == IOMUX_PC4_SEL_PC5) || \
+ ((IOMUX_PINFNC) == IOMUX_PC4_SEL_PC3) || ((IOMUX_PINFNC) == IOMUX_PC4_SEL_PC7) || \
+ ((IOMUX_PINFNC) == IOMUX_PC4_SEL_MASK) || ((IOMUX_PINFNC) == IOMUX_PD5_SEL_PD5) || \
+ ((IOMUX_PINFNC) == IOMUX_PD5_SEL_PD3) || ((IOMUX_PINFNC) == IOMUX_PD5_SEL_PD1) || \
+ ((IOMUX_PINFNC) == IOMUX_PD5_SEL_PC6) || ((IOMUX_PINFNC) == IOMUX_PD5_SEL_MASK) || \
+ ((IOMUX_PINFNC) == NRST_PINKEY) || ((IOMUX_PINFNC) == IOMUX_NRST_SEL_PA0))
+/**
+ * @}
+ */
+
+typedef enum
+{
+ TIM2_CN1_EXTERNAL = 0,
+ TIM2_CN1_HSIDIV,
+ TIM2_CN1_LSI_128,
+ TIM2_CN1_EXTERNAL_MAX
+}TIM2_SOURCE;
+
+#define IS_TIM2_SOURCE(TIM2_SOURCE) (((TIM2_SOURCE) == TIM2_CN1_EXTERNAL) || ((TIM2_SOURCE) == TIM2_CN1_HSIDIV) || \
+ ((TIM2_SOURCE) == TIM2_CN1_LSI_128) || ((TIM2_SOURCE) == TIM2_CN1_EXTERNAL_MAX))
+
+
+
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+/* Function used to set the GPIO configuration to the default reset state *****/
+void GPIO_DeInit(GPIO_TypeDef* GPIOx);
+
+/* Initialization and Configuration functions *********************************/
+void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
+void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct);
+void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
+
+/* GPIO Read and Write functions **********************************************/
+uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
+uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
+uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
+uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
+void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
+void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
+void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
+void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);
+void GPIO_Toggle(GPIO_TypeDef* GPIOx , uint16_t GPIO_Pin);
+
+/* GPIO Alternate functions configuration functions ***************************/
+void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF);
+/* GPIO IOMUX*/
+void GPIO_IOMUX_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t IOMUX_AF);
+void GPIO_IOMUX_ChangePin(IOMUX_PIN eIOMUX_Pinx, uint32_t eIOMUX_FuncPin);
+
+void GPIO_IOMUX_SetTIM2CN1_Source(TIM2_SOURCE TIM2CN1Source);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __HK32F030M_GPIO_H */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_i2c.h b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_i2c.h
new file mode 100644
index 0000000..b120ed3
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_i2c.h
@@ -0,0 +1,449 @@
+/**
+ ******************************************************************************
+ * @file hk32f030m_i2c.h
+ * @version V1.0.1
+ * @date 2019-12-16
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __HK32F030M_I2C_H
+#define __HK32F030M_I2C_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "hk32f030m.h"
+
+/** @addtogroup I2C
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+
+/**
+ * @brief I2C Init structure definition
+ */
+
+typedef struct
+{
+ uint32_t I2C_Timing; /*!< Specifies the I2C_TIMINGR_register value.
+ This parameter must be set by referring to I2C_Timing_Config_Tool*/
+
+ uint32_t I2C_AnalogFilter; /*!< Enables or disables analog noise filter.
+ This parameter can be a value of @ref I2C_Analog_Filter*/
+
+ uint32_t I2C_DigitalFilter; /*!< Configures the digital noise filter.
+ This parameter can be a number between 0x00 and 0x0F*/
+
+ uint32_t I2C_Mode; /*!< Specifies the I2C mode.
+ This parameter can be a value of @ref I2C_mode*/
+
+ uint32_t I2C_OwnAddress1; /*!< Specifies the device own address 1.
+ This parameter can be a 7-bit or 10-bit address*/
+
+ uint32_t I2C_Ack; /*!< Enables or disables the acknowledgement.
+ This parameter can be a value of @ref I2C_acknowledgement*/
+
+ uint32_t I2C_AcknowledgedAddress; /*!< Specifies if 7-bit or 10-bit address is acknowledged.
+ This parameter can be a value of @ref I2C_acknowledged_address*/
+}I2C_InitTypeDef;
+
+/* Exported constants --------------------------------------------------------*/
+
+
+/** @defgroup I2C_Exported_Constants
+ * @{
+ */
+
+#define IS_I2C_ALL_PERIPH(PERIPH) ((PERIPH) == I2C1)
+
+#define IS_I2C_1_PERIPH(PERIPH) ((PERIPH) == I2C1)
+
+/** @defgroup I2C_Analog_Filter
+ * @{
+ */
+
+#define I2C_AnalogFilter_Enable ((uint32_t)0x00000000)
+#define I2C_AnalogFilter_Disable I2C_CR1_ANFOFF
+
+#define IS_I2C_ANALOG_FILTER(FILTER) (((FILTER) == I2C_AnalogFilter_Enable) || \
+ ((FILTER) == I2C_AnalogFilter_Disable))
+/**
+ * @}
+ */
+
+/** @defgroup I2C_Digital_Filter
+ * @{
+ */
+
+#define IS_I2C_DIGITAL_FILTER(FILTER) ((FILTER) <= 0x0000000F)
+/**
+ * @}
+ */
+
+/** @defgroup I2C_mode
+ * @{
+ */
+
+#define I2C_Mode_I2C ((uint32_t)0x00000000)
+#define I2C_Mode_SMBusDevice I2C_CR1_SMBDEN
+#define I2C_Mode_SMBusHost I2C_CR1_SMBHEN
+
+#define IS_I2C_MODE(MODE) (((MODE) == I2C_Mode_I2C) || \
+ ((MODE) == I2C_Mode_SMBusDevice) || \
+ ((MODE) == I2C_Mode_SMBusHost))
+/**
+ * @}
+ */
+
+/** @defgroup I2C_acknowledgement
+ * @{
+ */
+
+#define I2C_Ack_Enable ((uint32_t)0x00000000)
+#define I2C_Ack_Disable I2C_CR2_NACK
+
+#define IS_I2C_ACK(ACK) (((ACK) == I2C_Ack_Enable) || \
+ ((ACK) == I2C_Ack_Disable))
+/**
+ * @}
+ */
+
+/** @defgroup I2C_acknowledged_address
+ * @{
+ */
+
+#define I2C_AcknowledgedAddress_7bit ((uint32_t)0x00000000)
+#define I2C_AcknowledgedAddress_10bit I2C_OAR1_OA1MODE
+
+#define IS_I2C_ACKNOWLEDGE_ADDRESS(ADDRESS) (((ADDRESS) == I2C_AcknowledgedAddress_7bit) || \
+ ((ADDRESS) == I2C_AcknowledgedAddress_10bit))
+/**
+ * @}
+ */
+
+/** @defgroup I2C_own_address1
+ * @{
+ */
+
+#define IS_I2C_OWN_ADDRESS1(ADDRESS1) ((ADDRESS1) <= (uint32_t)0x000003FF)
+/**
+ * @}
+ */
+
+/** @defgroup I2C_transfer_direction
+ * @{
+ */
+
+#define I2C_Direction_Transmitter ((uint16_t)0x0000)
+#define I2C_Direction_Receiver ((uint16_t)0x0400)
+
+#define IS_I2C_DIRECTION(DIRECTION) (((DIRECTION) == I2C_Direction_Transmitter) || \
+ ((DIRECTION) == I2C_Direction_Receiver))
+/**
+ * @}
+ */
+
+/** @defgroup I2C_DMA_transfer_requests
+ * @{
+ */
+
+#define I2C_DMAReq_Tx I2C_CR1_TXDMAEN
+#define I2C_DMAReq_Rx I2C_CR1_RXDMAEN
+
+#define IS_I2C_DMA_REQ(REQ) ((((REQ) & (uint32_t)0xFFFF3FFF) == 0x00) && ((REQ) != 0x00))
+/**
+ * @}
+ */
+
+/** @defgroup I2C_slave_address
+ * @{
+ */
+
+#define IS_I2C_SLAVE_ADDRESS(ADDRESS) ((ADDRESS) <= (uint16_t)0x03FF)
+/**
+ * @}
+ */
+
+
+/** @defgroup I2C_own_address2
+ * @{
+ */
+
+#define IS_I2C_OWN_ADDRESS2(ADDRESS2) ((ADDRESS2) <= (uint16_t)0x00FF)
+
+/**
+ * @}
+ */
+
+/** @defgroup I2C_own_address2_mask
+ * @{
+ */
+
+#define I2C_OA2_NoMask ((uint8_t)0x00)
+#define I2C_OA2_Mask01 ((uint8_t)0x01)
+#define I2C_OA2_Mask02 ((uint8_t)0x02)
+#define I2C_OA2_Mask03 ((uint8_t)0x03)
+#define I2C_OA2_Mask04 ((uint8_t)0x04)
+#define I2C_OA2_Mask05 ((uint8_t)0x05)
+#define I2C_OA2_Mask06 ((uint8_t)0x06)
+#define I2C_OA2_Mask07 ((uint8_t)0x07)
+
+#define IS_I2C_OWN_ADDRESS2_MASK(MASK) (((MASK) == I2C_OA2_NoMask) || \
+ ((MASK) == I2C_OA2_Mask01) || \
+ ((MASK) == I2C_OA2_Mask02) || \
+ ((MASK) == I2C_OA2_Mask03) || \
+ ((MASK) == I2C_OA2_Mask04) || \
+ ((MASK) == I2C_OA2_Mask05) || \
+ ((MASK) == I2C_OA2_Mask06) || \
+ ((MASK) == I2C_OA2_Mask07))
+
+/**
+ * @}
+ */
+
+/** @defgroup I2C_timeout
+ * @{
+ */
+
+#define IS_I2C_TIMEOUT(TIMEOUT) ((TIMEOUT) <= (uint16_t)0x0FFF)
+
+/**
+ * @}
+ */
+
+/** @defgroup I2C_registers
+ * @{
+ */
+
+#define I2C_Register_CR1 ((uint8_t)0x00)
+#define I2C_Register_CR2 ((uint8_t)0x04)
+#define I2C_Register_OAR1 ((uint8_t)0x08)
+#define I2C_Register_OAR2 ((uint8_t)0x0C)
+#define I2C_Register_TIMINGR ((uint8_t)0x10)
+#define I2C_Register_TIMEOUTR ((uint8_t)0x14)
+#define I2C_Register_ISR ((uint8_t)0x18)
+#define I2C_Register_ICR ((uint8_t)0x1C)
+#define I2C_Register_PECR ((uint8_t)0x20)
+#define I2C_Register_RXDR ((uint8_t)0x24)
+#define I2C_Register_TXDR ((uint8_t)0x28)
+
+#define IS_I2C_REGISTER(REGISTER) (((REGISTER) == I2C_Register_CR1) || \
+ ((REGISTER) == I2C_Register_CR2) || \
+ ((REGISTER) == I2C_Register_OAR1) || \
+ ((REGISTER) == I2C_Register_OAR2) || \
+ ((REGISTER) == I2C_Register_TIMINGR) || \
+ ((REGISTER) == I2C_Register_TIMEOUTR) || \
+ ((REGISTER) == I2C_Register_ISR) || \
+ ((REGISTER) == I2C_Register_ICR) || \
+ ((REGISTER) == I2C_Register_PECR) || \
+ ((REGISTER) == I2C_Register_RXDR) || \
+ ((REGISTER) == I2C_Register_TXDR))
+/**
+ * @}
+ */
+
+/** @defgroup I2C_interrupts_definition
+ * @{
+ */
+
+#define I2C_IT_ERRI I2C_CR1_ERRIE
+#define I2C_IT_TCI I2C_CR1_TCIE
+#define I2C_IT_STOPI I2C_CR1_STOPIE
+#define I2C_IT_NACKI I2C_CR1_NACKIE
+#define I2C_IT_ADDRI I2C_CR1_ADDRIE
+#define I2C_IT_RXI I2C_CR1_RXIE
+#define I2C_IT_TXI I2C_CR1_TXIE
+
+#define IS_I2C_CONFIG_IT(IT) ((((IT) & (uint32_t)0xFFFFFF01) == 0x00) && ((IT) != 0x00))
+
+/**
+ * @}
+ */
+
+/** @defgroup I2C_flags_definition
+ * @{
+ */
+
+#define I2C_FLAG_TXE I2C_ISR_TXE
+#define I2C_FLAG_TXIS I2C_ISR_TXIS
+#define I2C_FLAG_RXNE I2C_ISR_RXNE
+#define I2C_FLAG_ADDR I2C_ISR_ADDR
+#define I2C_FLAG_NACKF I2C_ISR_NACKF
+#define I2C_FLAG_STOPF I2C_ISR_STOPF
+#define I2C_FLAG_TC I2C_ISR_TC
+#define I2C_FLAG_TCR I2C_ISR_TCR
+#define I2C_FLAG_BERR I2C_ISR_BERR
+#define I2C_FLAG_ARLO I2C_ISR_ARLO
+#define I2C_FLAG_OVR I2C_ISR_OVR
+#define I2C_FLAG_PECERR I2C_ISR_PECERR
+#define I2C_FLAG_TIMEOUT I2C_ISR_TIMEOUT
+#define I2C_FLAG_ALERT I2C_ISR_ALERT
+#define I2C_FLAG_BUSY I2C_ISR_BUSY
+
+#define IS_I2C_CLEAR_FLAG(FLAG) ((((FLAG) & (uint32_t)0xFFFF4000) == 0x00) && ((FLAG) != 0x00))
+
+#define IS_I2C_GET_FLAG(FLAG) (((FLAG) == I2C_FLAG_TXE) || ((FLAG) == I2C_FLAG_TXIS) || \
+ ((FLAG) == I2C_FLAG_RXNE) || ((FLAG) == I2C_FLAG_ADDR) || \
+ ((FLAG) == I2C_FLAG_NACKF) || ((FLAG) == I2C_FLAG_STOPF) || \
+ ((FLAG) == I2C_FLAG_TC) || ((FLAG) == I2C_FLAG_TCR) || \
+ ((FLAG) == I2C_FLAG_BERR) || ((FLAG) == I2C_FLAG_ARLO) || \
+ ((FLAG) == I2C_FLAG_OVR) || ((FLAG) == I2C_FLAG_PECERR) || \
+ ((FLAG) == I2C_FLAG_TIMEOUT) || ((FLAG) == I2C_FLAG_ALERT) || \
+ ((FLAG) == I2C_FLAG_BUSY))
+
+/**
+ * @}
+ */
+
+
+/** @defgroup I2C_interrupts_definition
+ * @{
+ */
+
+#define I2C_IT_TXIS I2C_ISR_TXIS
+#define I2C_IT_RXNE I2C_ISR_RXNE
+#define I2C_IT_ADDR I2C_ISR_ADDR
+#define I2C_IT_NACKF I2C_ISR_NACKF
+#define I2C_IT_STOPF I2C_ISR_STOPF
+#define I2C_IT_TC I2C_ISR_TC
+#define I2C_IT_TCR I2C_ISR_TCR
+#define I2C_IT_BERR I2C_ISR_BERR
+#define I2C_IT_ARLO I2C_ISR_ARLO
+#define I2C_IT_OVR I2C_ISR_OVR
+#define I2C_IT_PECERR I2C_ISR_PECERR
+#define I2C_IT_TIMEOUT I2C_ISR_TIMEOUT
+#define I2C_IT_ALERT I2C_ISR_ALERT
+
+#define IS_I2C_CLEAR_IT(IT) ((((IT) & (uint32_t)0xFFFFC001) == 0x00) && ((IT) != 0x00))
+
+#define IS_I2C_GET_IT(IT) (((IT) == I2C_IT_TXIS) || ((IT) == I2C_IT_RXNE) || \
+ ((IT) == I2C_IT_ADDR) || ((IT) == I2C_IT_NACKF) || \
+ ((IT) == I2C_IT_STOPF) || ((IT) == I2C_IT_TC) || \
+ ((IT) == I2C_IT_TCR) || ((IT) == I2C_IT_BERR) || \
+ ((IT) == I2C_IT_ARLO) || ((IT) == I2C_IT_OVR) || \
+ ((IT) == I2C_IT_PECERR) || ((IT) == I2C_IT_TIMEOUT) || \
+ ((IT) == I2C_IT_ALERT))
+
+
+/**
+ * @}
+ */
+
+/** @defgroup I2C_ReloadEndMode_definition
+ * @{
+ */
+
+#define I2C_Reload_Mode I2C_CR2_RELOAD
+#define I2C_AutoEnd_Mode I2C_CR2_AUTOEND
+#define I2C_SoftEnd_Mode ((uint32_t)0x00000000)
+
+
+#define IS_RELOAD_END_MODE(MODE) (((MODE) == I2C_Reload_Mode) || \
+ ((MODE) == I2C_AutoEnd_Mode) || \
+ ((MODE) == I2C_SoftEnd_Mode))
+
+
+/**
+ * @}
+ */
+
+/** @defgroup I2C_StartStopMode_definition
+ * @{
+ */
+
+#define I2C_No_StartStop ((uint32_t)0x00000000)
+#define I2C_Generate_Stop I2C_CR2_STOP
+#define I2C_Generate_Start_Read (uint32_t)(I2C_CR2_START | I2C_CR2_RD_WRN)
+#define I2C_Generate_Start_Write I2C_CR2_START
+
+
+#define IS_START_STOP_MODE(MODE) (((MODE) == I2C_Generate_Stop) || \
+ ((MODE) == I2C_Generate_Start_Read) || \
+ ((MODE) == I2C_Generate_Start_Write) || \
+ ((MODE) == I2C_No_StartStop))
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+
+
+/* Initialization and Configuration functions *********************************/
+void I2C_DeInit(I2C_TypeDef* I2Cx);
+void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitStruct);
+void I2C_StructInit(I2C_InitTypeDef* I2C_InitStruct);
+void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
+void I2C_SoftwareResetCmd(I2C_TypeDef* I2Cx);
+void I2C_ITConfig(I2C_TypeDef* I2Cx, uint32_t I2C_IT, FunctionalState NewState);
+void I2C_StretchClockCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
+void I2C_StopModeCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
+void I2C_DualAddressCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
+void I2C_OwnAddress2Config(I2C_TypeDef* I2Cx, uint16_t Address, uint8_t Mask);
+void I2C_GeneralCallCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
+void I2C_SlaveByteControlCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
+void I2C_SlaveAddressConfig(I2C_TypeDef* I2Cx, uint16_t Address);
+void I2C_10BitAddressingModeCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
+
+/* Communications handling functions ******************************************/
+void I2C_AutoEndCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
+void I2C_ReloadCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
+void I2C_NumberOfBytesConfig(I2C_TypeDef* I2Cx, uint8_t Number_Bytes);
+void I2C_MasterRequestConfig(I2C_TypeDef* I2Cx, uint16_t I2C_Direction);
+void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState);
+void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState);
+void I2C_10BitAddressHeaderCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
+void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState);
+uint8_t I2C_GetAddressMatched(I2C_TypeDef* I2Cx);
+uint16_t I2C_GetTransferDirection(I2C_TypeDef* I2Cx);
+void I2C_TransferHandling(I2C_TypeDef* I2Cx, uint16_t Address, uint8_t Number_Bytes, uint32_t ReloadEndMode, uint32_t StartStopMode);
+
+/* SMBUS management functions ************************************************/
+void I2C_SMBusAlertCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
+void I2C_ClockTimeoutCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
+void I2C_ExtendedClockTimeoutCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
+void I2C_IdleClockTimeoutCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
+void I2C_TimeoutAConfig(I2C_TypeDef* I2Cx, uint16_t Timeout);
+void I2C_TimeoutBConfig(I2C_TypeDef* I2Cx, uint16_t Timeout);
+void I2C_CalculatePEC(I2C_TypeDef* I2Cx, FunctionalState NewState);
+void I2C_PECRequestCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
+uint8_t I2C_GetPEC(I2C_TypeDef* I2Cx);
+
+/* I2C registers management functions *****************************************/
+uint32_t I2C_ReadRegister(I2C_TypeDef* I2Cx, uint8_t I2C_Register);
+
+/* Data transfers management functions ****************************************/
+void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data);
+uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx);
+
+/* Interrupts and flags management functions **********************************/
+FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG);
+void I2C_ClearFlag(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG);
+ITStatus I2C_GetITStatus(I2C_TypeDef* I2Cx, uint32_t I2C_IT);
+void I2C_ClearITPendingBit(I2C_TypeDef* I2Cx, uint32_t I2C_IT);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__HK32F030M_I2C_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_iwdg.h b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_iwdg.h
new file mode 100644
index 0000000..aab1b2f
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_iwdg.h
@@ -0,0 +1,112 @@
+/**
+ ******************************************************************************
+ * @file hk32f030m_iwdg.h
+ * @version V1.0.0
+ * author Rakan.Z/wing.w
+ * @date 2019-08-15
+ ******************************************************************************
+/
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __HK32F030M_IWDG_H
+#define __HK32F030M_IWDG_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "hk32f030m.h"
+
+/** @addtogroup IWDG
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup IWDG_Exported_Constants
+ * @{
+ */
+
+/** @defgroup IWDG_WriteAccess
+ * @{
+ */
+
+#define IWDG_WriteAccess_Enable ((uint16_t)0x5555)
+#define IWDG_WriteAccess_Disable ((uint16_t)0x0000)
+#define IS_IWDG_WRITE_ACCESS(ACCESS) (((ACCESS) == IWDG_WriteAccess_Enable) || \
+ ((ACCESS) == IWDG_WriteAccess_Disable))
+/**
+ * @}
+ */
+
+/** @defgroup IWDG_prescaler
+ * @{
+ */
+
+#define IWDG_Prescaler_4 ((uint8_t)0x00)
+#define IWDG_Prescaler_8 ((uint8_t)0x01)
+#define IWDG_Prescaler_16 ((uint8_t)0x02)
+#define IWDG_Prescaler_32 ((uint8_t)0x03)
+#define IWDG_Prescaler_64 ((uint8_t)0x04)
+#define IWDG_Prescaler_128 ((uint8_t)0x05)
+#define IWDG_Prescaler_256 ((uint8_t)0x06)
+#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))
+/**
+ * @}
+ */
+
+/** @defgroup IWDG_Flag
+ * @{
+ */
+
+#define IWDG_FLAG_PVU IWDG_SR_PVU
+#define IWDG_FLAG_RVU IWDG_SR_RVU
+#define IWDG_FLAG_WVU IWDG_SR_WVU
+#define IS_IWDG_FLAG(FLAG) (((FLAG) == IWDG_FLAG_PVU) || ((FLAG) == IWDG_FLAG_RVU) || \
+ ((FLAG) == IWDG_FLAG_WVU))
+
+#define IS_IWDG_RELOAD(RELOAD) ((RELOAD) <= 0xFFF)
+
+#define IS_IWDG_WINDOW_VALUE(VALUE) ((VALUE) <= 0xFFF)
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+
+/* Prescaler and Counter configuration functions ******************************/
+void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess);
+void IWDG_SetPrescaler(uint8_t IWDG_Prescaler);
+void IWDG_SetReload(uint16_t Reload);
+void IWDG_ReloadCounter(void);
+void IWDG_SetWindowValue(uint16_t WindowValue);
+
+/* IWDG activation function ***************************************************/
+void IWDG_Enable(void);
+
+/* Flag management function ***************************************************/
+FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __HK32F030M_IWDG_H */
+
+
+
+
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_misc.h b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_misc.h
new file mode 100644
index 0000000..fbe843e
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_misc.h
@@ -0,0 +1,117 @@
+/**
+ ******************************************************************************
+ * @file hk32f030m_misc.h
+ * @version V1.0.1
+ * @date 2019-08-15
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __HK32F030M_MISC_H
+#define __HK32F030M_MISC_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "hk32f030m.h"
+
+
+/** @addtogroup MISC
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+
+/**
+ * @brief NVIC Init Structure definition
+ */
+
+typedef struct
+{
+ uint8_t NVIC_IRQChannel; /*!< Specifies the IRQ channel to be enabled or disabled.
+ This parameter can be a value of @ref IRQn_Type
+ (For the complete HK32 Devices IRQ Channels list,
+ please refer to hk32f030m.h file) */
+
+ uint8_t NVIC_IRQChannelPriority; /*!< Specifies the priority level for the IRQ channel specified
+ in NVIC_IRQChannel. This parameter can be a value
+ between 0 and 3. */
+
+ FunctionalState NVIC_IRQChannelCmd; /*!< Specifies whether the IRQ channel defined in NVIC_IRQChannel
+ will be enabled or disabled.
+ This parameter can be set either to ENABLE or DISABLE */
+} NVIC_InitTypeDef;
+
+/**
+ *
+@verbatim
+
+@endverbatim
+*/
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup MISC_Exported_Constants
+ * @{
+ */
+
+/** @defgroup MISC_System_Low_Power
+ * @{
+ */
+
+#define NVIC_LP_SEVONPEND ((uint8_t)0x10)
+#define NVIC_LP_SLEEPDEEP ((uint8_t)0x04)
+#define NVIC_LP_SLEEPONEXIT ((uint8_t)0x02)
+#define IS_NVIC_LP(LP) (((LP) == NVIC_LP_SEVONPEND) || \
+ ((LP) == NVIC_LP_SLEEPDEEP) || \
+ ((LP) == NVIC_LP_SLEEPONEXIT))
+/**
+ * @}
+ */
+
+/** @defgroup MISC_Preemption_Priority_Group
+ * @{
+ */
+#define IS_NVIC_PRIORITY(PRIORITY) ((PRIORITY) < 0x04)
+
+/**
+ * @}
+ */
+
+/** @defgroup MISC_SysTick_clock_source
+ * @{
+ */
+
+#define SysTick_CLKSource_HCLK_Div8 ((uint32_t)0xFFFFFFFB)
+#define SysTick_CLKSource_HCLK ((uint32_t)0x00000004)
+#define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SysTick_CLKSource_HCLK) || \
+ ((SOURCE) == SysTick_CLKSource_HCLK_Div8))
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+
+void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);
+void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState);
+void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __HK32F030M_MISC_H */
+
+
+
+/**
+ * @}
+ */
+
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_pwr.h b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_pwr.h
new file mode 100644
index 0000000..be71ed8
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_pwr.h
@@ -0,0 +1,68 @@
+/**
+ ******************************************************************************
+ * @file hk32f030m_pwr.h
+ * @author Rakan.z
+ * @version V1.0
+ * @brief Header file of PWR module
+ * @changelist
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __HK32F030M_PWR_H
+#define __HK32F030M_PWR_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "hk32f030m.h"
+
+/* ------------------ PWR registers bit mask ------------------------ */
+
+/* CR register bit mask */
+#define CR_DS_MASK ((uint32_t)0xFFFFFFFE)
+
+
+/** @defgroup Regulator_state_is_STOP_mode
+ * @{
+ */
+
+#define PWR_Regulator_LowPower ((uint32_t)0x00000001)
+#define IS_PWR_REGULATOR(REGULATOR) ((REGULATOR) == PWR_Regulator_LowPower)
+
+/** @defgroup PWR_mode_entry
+ * @{
+ */
+
+#define PWR_Entry_WFI ((uint8_t)0x01)
+#define PWR_Entry_WFE ((uint8_t)0x02)
+#define IS_PWR_ENTRY(ENTRY) (((ENTRY) == PWR_Entry_WFI) || ((ENTRY) == PWR_Entry_WFE))
+
+/** @defgroup PWR_LDO_VREF
+ * @{
+ */
+#define ADC_VREF_0D8 ((uint16_t)0x0008)
+#define ADC_VREF_LDO ((uint16_t)0x000C)
+#define VTEST_SET_MASK ((uint16_t)0x3FFF)
+#define IS_PWR_VTEST_SET(VTEST_SET) (((VTEST_SET) == ADC_VREF_0D8) || ((VTEST_SET) == ADC_VREF_LDO))
+
+
+
+
+void PWR_DeInit(void);
+
+void PWR_EnterSleepMode(uint8_t PWR_Entry);
+void PWR_EnterDeepSleepMode(uint8_t PWR_Entry);
+void PWR_EnterStopMode(uint32_t PWR_Regulator, uint8_t PWR_Entry);
+
+void PWR_SetLDO_RefVolToADC(uint16_t Vref_Set);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_rcc.h b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_rcc.h
new file mode 100644
index 0000000..54e7e1f
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_rcc.h
@@ -0,0 +1,288 @@
+/**
+ ******************************************************************************
+ * @file hk32f030m_rcc.h
+ * @author laura.C
+ * @version V1.0
+ * @brief API file of RCC module
+ * @changelist
+ ******************************************************************************
+ */
+
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __HK32F030M_RCC_H
+#define __HK32F030M_RCC_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "hk32f030m.h"
+
+/* Exported types ------------------------------------------------------------*/
+
+typedef struct
+{
+ uint32_t SYSCLK_Frequency;
+ uint32_t HCLK_Frequency;
+ uint32_t PCLK_Frequency;
+ uint32_t ADCCLK_Frequency;
+ uint32_t I2C1CLK_Frequency;
+ uint32_t USART1CLK_Frequency;
+}RCC_ClocksTypeDef;
+
+/* Exported constants --------------------------------------------------------*/
+
+
+
+/** RCC_System_Clock_Source */
+
+#define RCC_SYSCLKSource_HSI RCC_CFGR_SW_HSI
+#define RCC_SYSCLKSource_EXTCLK RCC_CFGR_SW_EXTCLK
+#define RCC_SYSCLKSource_LSI RCC_CFGR_SW_LSI
+
+
+#define IS_RCC_SYSCLK_SOURCE(SOURCE) (((SOURCE) == RCC_SYSCLKSource_HSI) || \
+ ((SOURCE) == RCC_SYSCLKSource_EXTCLK) || \
+ ((SOURCE) == RCC_SYSCLKSource_LSI))
+
+/** RCC_AHB_Clock_Source */
+
+#define RCC_SYSCLK_Div1 RCC_CFGR_HPRE_DIV1
+#define RCC_SYSCLK_Div2 RCC_CFGR_HPRE_DIV2
+#define RCC_SYSCLK_Div4 RCC_CFGR_HPRE_DIV4
+#define RCC_SYSCLK_Div6 RCC_CFGR_HPRE_DIV6
+#define RCC_SYSCLK_Div8 RCC_CFGR_HPRE_DIV8
+#define RCC_SYSCLK_Div16 RCC_CFGR_HPRE_DIV16
+#define RCC_SYSCLK_Div64 RCC_CFGR_HPRE_DIV64
+#define RCC_SYSCLK_Div128 RCC_CFGR_HPRE_DIV128
+#define RCC_SYSCLK_Div256 RCC_CFGR_HPRE_DIV256
+#define RCC_SYSCLK_Div512 RCC_CFGR_HPRE_DIV512
+#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_Div128) ||((HCLK) == RCC_SYSCLK_Div6))
+
+
+/** RCC_APB_Clock_Source */
+
+#define RCC_HCLK_Div1 RCC_CFGR_PPRE_DIV1
+#define RCC_HCLK_Div2 RCC_CFGR_PPRE_DIV2
+#define RCC_HCLK_Div4 RCC_CFGR_PPRE_DIV4
+#define RCC_HCLK_Div8 RCC_CFGR_PPRE_DIV8
+#define RCC_HCLK_Div16 RCC_CFGR_PPRE_DIV16
+#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))
+
+/** RCC_ADC_clock_source */
+#define RCC_ADCCLK_HSI32M_Div1 ((uint32_t)0x00000000)
+#define RCC_ADCCLK_HSI32M_Div1_5 ((uint32_t)0x04000000)
+#define RCC_ADCCLK_HSI32M_Div2 ((uint32_t)0x08000000)
+#define RCC_ADCCLK_HSI32M_Div2_5 ((uint32_t)0x0C000000)
+#define RCC_ADCCLK_HSI32M_Div3 ((uint32_t)0x10000000)
+#define RCC_ADCCLK_HSI32M_Div3_5 ((uint32_t)0x14000000)
+#define RCC_ADCCLK_HSI32M_Div4 ((uint32_t)0x18000000)
+#define RCC_ADCCLK_HSI32M_Div4_5 ((uint32_t)0x1C000000)
+#define RCC_ADCCLK_HSI32M_Div5 ((uint32_t)0x20000000)
+#define RCC_ADCCLK_HSI32M_Div5_5 ((uint32_t)0x24000000)
+#define RCC_ADCCLK_HSI32M_Div6 ((uint32_t)0x28000000)
+#define RCC_ADCCLK_HSI32M_Div6_5 ((uint32_t)0x2C000000)
+#define RCC_ADCCLK_HSI32M_Div7 ((uint32_t)0x30000000)
+#define RCC_ADCCLK_HSI32M_Div7_5 ((uint32_t)0x34000000)
+#define RCC_ADCCLK_HSI32M_Div8 ((uint32_t)0x38000000)
+#define RCC_ADCCLK_HSI32M_Div8_5 ((uint32_t)0x3C000000)
+#define RCC_ADCCLK_HSI32M_Div9 ((uint32_t)0x40000000)
+#define RCC_ADCCLK_HSI32M_Div9_5 ((uint32_t)0x44000000)
+#define RCC_ADCCLK_HSI32M_Div10 ((uint32_t)0x48000000)
+#define RCC_ADCCLK_HSI32M_Div10_5 ((uint32_t)0x4C000000)
+#define RCC_ADCCLK_HSI32M_Div11 ((uint32_t)0x50000000)
+#define RCC_ADCCLK_HSI32M_Div11_5 ((uint32_t)0x54000000)
+#define RCC_ADCCLK_HSI32M_Div12 ((uint32_t)0x58000000)
+#define RCC_ADCCLK_HSI32M_Div12_5 ((uint32_t)0x5C000000)
+#define RCC_ADCCLK_HSI32M_Div13 ((uint32_t)0x60000000)
+#define RCC_ADCCLK_HSI32M_Div13_5 ((uint32_t)0x64000000)
+#define RCC_ADCCLK_HSI32M_Div14 ((uint32_t)0x68000000)
+#define RCC_ADCCLK_HSI32M_Div14_5 ((uint32_t)0x6C000000)
+#define RCC_ADCCLK_HSI32M_Div15 ((uint32_t)0x70000000)
+#define RCC_ADCCLK_HSI32M_Div15_5 ((uint32_t)0x74000000)
+#define RCC_ADCCLK_HSI32M_Div16 ((uint32_t)0x78000000)
+#define RCC_ADCCLK_HSI32M_Div16_5 ((uint32_t)0x7C000000)
+
+#define RCC_CFGR4_ADCHSIPRE ((uint32_t)0x7C000000)
+
+#define RCC_ADCCLK_PCLK_DIV2 ADC_CFGR2_CKMODE_0
+#define RCC_ADCCLK_PCLK_DIV4 ADC_CFGR2_CKMODE_1
+
+/** RCC_I2C_clock_source */
+
+#define RCC_I2C1CLK_HSI ((uint32_t)0x00000000)
+#define RCC_I2C1CLK_SYSCLK RCC_CFGR3_I2C1SW
+
+#define IS_RCC_I2CCLK(I2CCLK) (((I2CCLK) == RCC_I2C1CLK_HSI) || ((I2CCLK) == RCC_I2C1CLK_SYSCLK))
+
+
+/** RCC_USART_clock_source */
+#define RCC_USART1CLK_PCLK ((uint32_t)0x00000000)
+#define RCC_USART1CLK_SYSCLK ((uint32_t)0x00000001)
+#define RCC_USART1CLK_HSI ((uint32_t)0x00000003)
+
+#define IS_RCC_USARTCLK(USARTCLK) (((USARTCLK) == RCC_USART1CLK_PCLK) || \
+ ((USARTCLK) == RCC_USART1CLK_SYSCLK) || \
+ ((USARTCLK) == RCC_USART1CLK_HSI))
+
+/** RCC_Interrupt_Source */
+#define RCC_IT_LSIRDY ((uint8_t)0x01)
+#define RCC_IT_HSIRDY ((uint8_t)0x04)
+#define RCC_IT_EXTRDY ((uint8_t)0x08)
+#define RCC_IT_CSS ((uint8_t)0x80)
+
+#define IS_RCC_GET_IT(IT) (((IT) == RCC_IT_LSIRDY) || ((IT) == RCC_IT_HSIRDY) || \
+ ((IT) == RCC_IT_CSS) || ((IT) == RCC_IT_EXTRDY))
+
+#define IS_RCC_CLEAR_IT(IT) ((IT) != 0x00)
+
+
+/** RCC_AHB_Peripherals */
+#define RCC_AHBPeriph_GPIOA RCC_AHBENR_GPIOAEN
+#define RCC_AHBPeriph_GPIOB RCC_AHBENR_GPIOBEN
+#define RCC_AHBPeriph_GPIOC RCC_AHBENR_GPIOCEN
+#define RCC_AHBPeriph_GPIOD RCC_AHBENR_GPIODEN
+#define RCC_AHBPeriph_CRC RCC_AHBENR_CRCEN
+#define RCC_AHBPeriph_FLITF RCC_AHBENR_FLITFEN
+#define RCC_AHBPeriph_SRAM RCC_AHBENR_SRAMEN
+
+
+#define IS_RCC_AHB_PERIPH(PERIPH) ((((PERIPH) & 0xFFE1FFAB) == 0x00) && ((PERIPH) != 0x00))
+#define IS_RCC_AHB_RST_PERIPH(PERIPH) ((((PERIPH) & 0xFFE1FFAB) == 0x00) && ((PERIPH) != 0x00))
+
+
+
+/** RCC_APB2_Peripherals */
+
+#define RCC_APB2Periph_SYSCFG RCC_APB2ENR_SYSCFGEN
+#define RCC_APB2Periph_ADC RCC_APB2ENR_ADCEN
+#define RCC_APB2Periph_TIM1 RCC_APB2ENR_TIM1EN
+#define RCC_APB2Periph_SPI1 RCC_APB2ENR_SPI1EN
+#define RCC_APB2Periph_USART1 RCC_APB2ENR_USART1EN
+#define RCC_APB2Periph_DBGMCU RCC_APB2ENR_DBGMCUEN
+
+#define IS_RCC_APB2_PERIPH(PERIPH) ((((PERIPH) & 0xFFB8A51E) == 0x00) && ((PERIPH) != 0x00))
+
+
+/** RCC_APB1_Peripherals */
+#define RCC_APB1Periph_TIM2 RCC_APB1ENR_TIM2EN
+#define RCC_APB1Periph_TIM6 RCC_APB1ENR_TIM6EN
+#define RCC_APB1Periph_WWDG RCC_APB1ENR_WWDGEN
+#define RCC_APB1Periph_AWU RCC_APB1ENR_AWUEN
+#define RCC_APB1Periph_I2C1 RCC_APB1ENR_I2C1EN
+#define RCC_APB1Periph_PWR RCC_APB1ENR_PWREN
+#define RCC_APB1Periph_BEEPER RCC_APB1ENR_BEEPEREN
+#define RCC_APB1Periph_IOMUX RCC_APB1ENR_IOMUXEN
+
+#define IS_RCC_APB1_PERIPH(PERIPH) ((((PERIPH) & 0x8FDEF7EE) == 0x00) && ((PERIPH) != 0x00))
+
+/** RCC_MCO_Clock_Source */
+
+#define RCC_MCOSource_NoClock ((uint8_t)0x00)
+#define RCC_MCOSource_LSI ((uint8_t)0x02)
+#define RCC_MCOSource_SYSCLK ((uint8_t)0x04)
+#define RCC_MCOSource_HSI ((uint8_t)0x05)
+
+
+#define IS_RCC_MCO_SOURCE(SOURCE) (((SOURCE) == RCC_MCOSource_NoClock) || ((SOURCE) == RCC_MCOSource_SYSCLK) ||\
+ ((SOURCE) == RCC_MCOSource_HSI) || ((SOURCE) == RCC_MCOSource_LSI))
+
+
+/** RCC_MCOPrescaler */
+
+#define RCC_MCOPrescaler_1 ((uint32_t)0x00000000)
+#define RCC_MCOPrescaler_2 ((uint32_t)0x10000000)
+#define RCC_MCOPrescaler_4 ((uint32_t)0x20000000)
+#define RCC_MCOPrescaler_8 ((uint32_t)0x30000000)
+#define RCC_MCOPrescaler_16 ((uint32_t)0x40000000)
+#define RCC_MCOPrescaler_32 ((uint32_t)0x50000000)
+#define RCC_MCOPrescaler_64 ((uint32_t)0x60000000)
+#define RCC_MCOPrescaler_128 ((uint32_t)0x70000000)
+
+#define IS_RCC_MCO_PRESCALER(PRESCALER) (((PRESCALER) == RCC_MCOPrescaler_1) || \
+ ((PRESCALER) == RCC_MCOPrescaler_2) || \
+ ((PRESCALER) == RCC_MCOPrescaler_4) || \
+ ((PRESCALER) == RCC_MCOPrescaler_8) || \
+ ((PRESCALER) == RCC_MCOPrescaler_16) || \
+ ((PRESCALER) == RCC_MCOPrescaler_32) || \
+ ((PRESCALER) == RCC_MCOPrescaler_64) || \
+ ((PRESCALER) == RCC_MCOPrescaler_128))
+
+/** @defgroup RCC_Flag */
+
+#define RCC_FLAG_HSIRDY ((uint8_t)0x21)
+#define RCC_FLAG_EXTCLKDY ((uint8_t)0x31)
+#define RCC_FLAG_LSIRDY ((uint8_t)0x61)
+#define RCC_FLAG_PINRST ((uint8_t)0x7A)
+#define RCC_FLAG_PORRST ((uint8_t)0x7B)
+#define RCC_FLAG_SFTRST ((uint8_t)0x7C)
+#define RCC_FLAG_IWDGRST ((uint8_t)0x7D)
+#define RCC_FLAG_WWDGRST ((uint8_t)0x7E)
+#define RCC_FLAG_LPWRRST ((uint8_t)0x7F)
+
+
+ #define IS_RCC_FLAG(FLAG) (((FLAG) == RCC_FLAG_HSIRDY) || ((FLAG) == RCC_FLAG_EXTCLKDY) || \
+ ((FLAG) == RCC_FLAG_LSIRDY) || ((FLAG) == RCC_FLAG_PORRST) || \
+ ((FLAG) == RCC_FLAG_PINRST) || ((FLAG) == RCC_FLAG_SFTRST) || \
+ ((FLAG) == RCC_FLAG_IWDGRST)|| ((FLAG) == RCC_FLAG_PINRST) || \
+ ((FLAG) == RCC_FLAG_WWDGRST)|| ((FLAG) == RCC_FLAG_LPWRRST))
+
+#define IS_RCC_HSI_CALIBRATION_VALUE(VALUE) ((VALUE) <= 0x1F)
+
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+
+/* Function used to set the RCC clock configuration to the default reset state */
+void RCC_DeInit(void);
+
+/* Internal clocks, CSS and MCO configuration functions *********/
+ErrorStatus RCC_WaitForStartUp(uint8_t RCC_FLAG);
+void RCC_AdjustHSICalibrationValue(uint8_t HSICalibrationValue);
+void RCC_HSICmd(FunctionalState NewState);
+void RCC_LSICmd(FunctionalState NewState);
+void RCC_EXTCmd(FunctionalState NewState, uint32_t EXTCKL_SEL);
+void RCC_ClockSecuritySystemCmd(FunctionalState NewState);
+void RCC_MCOConfig(uint8_t RCC_MCOSource,uint32_t RCC_MCOPrescaler);
+
+
+/* System, AHB and APB busses clocks configuration functions ******************/
+void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource);
+uint8_t RCC_GetSYSCLKSource(void);
+void RCC_HCLKConfig(uint32_t RCC_SYSCLK);
+void RCC_PCLKConfig(uint32_t RCC_HCLK);
+void RCC_ADCCLKConfig(uint32_t RCC_ADCCLK);
+void RCC_I2CCLKConfig(uint32_t RCC_I2CCLK);
+void RCC_USARTCLKConfig(uint32_t RCC_USARTCLK);
+void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks);
+
+/* Peripheral clocks configuration functions **********************************/
+void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState);
+void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
+void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
+void RCC_AHBPeriphResetCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState);
+void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
+void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
+
+/* Interrupts and flags management functions **********************************/
+void RCC_ITConfig(uint8_t RCC_IT, FunctionalState NewState);
+FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG);
+void RCC_ClearFlag(void);
+ITStatus RCC_GetITStatus(uint8_t RCC_IT);
+void RCC_ClearITPendingBit(uint8_t RCC_IT);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __HK32F030M_RCC_H */
+
+
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_spi.h b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_spi.h
new file mode 100644
index 0000000..d4f2c18
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_spi.h
@@ -0,0 +1,561 @@
+/**
+ ******************************************************************************
+ * @file hk32f030m_spi.h
+ * @version V1.0.1
+ * @date 2019-12-16
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __HK32F030M_SPI_H
+#define __HK32F030M_SPI_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "hk32f030m.h"
+
+
+/** @addtogroup SPI
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+
+/**
+ * @brief SPI Init structure definition
+ */
+
+typedef struct
+{
+ uint16_t SPI_Direction; /*!< Specifies the SPI unidirectional or bidirectional data mode.
+ This parameter can be a value of @ref SPI_data_direction */
+
+ uint16_t SPI_Mode; /*!< Specifies the SPI mode (Master/Slave).
+ This parameter can be a value of @ref SPI_mode */
+
+ uint16_t SPI_DataSize; /*!< Specifies the SPI data size.
+ This parameter can be a value of @ref SPI_data_size */
+
+ uint16_t SPI_CPOL; /*!< Specifies the serial clock steady state.
+ This parameter can be a value of @ref SPI_Clock_Polarity */
+
+ uint16_t SPI_CPHA; /*!< Specifies the clock active edge for the bit capture.
+ This parameter can be a value of @ref SPI_Clock_Phase */
+
+ uint16_t SPI_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 */
+
+ uint16_t SPI_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. */
+
+ uint16_t SPI_FirstBit; /*!< Specifies whether data transfers start from MSB or LSB bit.
+ This parameter can be a value of @ref SPI_MSB_LSB_transmission */
+
+ uint16_t SPI_CRCPolynomial; /*!< Specifies the polynomial used for the CRC calculation. */
+}SPI_InitTypeDef;
+
+
+/**
+ * @brief I2S Init structure definition
+
+ */
+
+typedef struct
+{
+ uint16_t I2S_Mode; /*!< Specifies the I2S operating mode.
+ This parameter can be a value of @ref SPI_I2S_Mode */
+
+ uint16_t I2S_Standard; /*!< Specifies the standard used for the I2S communication.
+ This parameter can be a value of @ref SPI_I2S_Standard */
+
+ uint16_t I2S_DataFormat; /*!< Specifies the data format for the I2S communication.
+ This parameter can be a value of @ref SPI_I2S_Data_Format */
+
+ uint16_t I2S_MCLKOutput; /*!< Specifies whether the I2S MCLK output is enabled or not.
+ This parameter can be a value of @ref SPI_I2S_MCLK_Output */
+
+ uint32_t I2S_AudioFreq; /*!< Specifies the frequency selected for the I2S communication.
+ This parameter can be a value of @ref SPI_I2S_Audio_Frequency */
+
+ uint16_t I2S_CPOL; /*!< Specifies the idle state of the I2S clock.
+ This parameter can be a value of @ref SPI_I2S_Clock_Polarity */
+}I2S_InitTypeDef;
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup SPI_Exported_Constants
+ * @{
+ */
+
+#define IS_SPI_ALL_PERIPH(PERIPH) ((PERIPH) == SPI1)
+
+#define IS_SPI_1_PERIPH(PERIPH) (((PERIPH) == SPI1))
+
+/** @defgroup SPI_data_direction
+ * @{
+ */
+
+#define SPI_Direction_2Lines_FullDuplex ((uint16_t)0x0000)
+#define SPI_Direction_2Lines_RxOnly ((uint16_t)0x0400)
+#define SPI_Direction_1Line_Rx ((uint16_t)0x8000)
+#define SPI_Direction_1Line_Tx ((uint16_t)0xC000)
+#define IS_SPI_DIRECTION_MODE(MODE) (((MODE) == SPI_Direction_2Lines_FullDuplex) || \
+ ((MODE) == SPI_Direction_2Lines_RxOnly) || \
+ ((MODE) == SPI_Direction_1Line_Rx) || \
+ ((MODE) == SPI_Direction_1Line_Tx))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_mode
+ * @{
+ */
+
+#define SPI_Mode_Master ((uint16_t)0x0104)
+#define SPI_Mode_Slave ((uint16_t)0x0000)
+#define IS_SPI_MODE(MODE) (((MODE) == SPI_Mode_Master) || \
+ ((MODE) == SPI_Mode_Slave))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_data_size
+ * @{
+ */
+
+#define SPI_DataSize_4b ((uint16_t)0x0300)
+#define SPI_DataSize_5b ((uint16_t)0x0400)
+#define SPI_DataSize_6b ((uint16_t)0x0500)
+#define SPI_DataSize_7b ((uint16_t)0x0600)
+#define SPI_DataSize_8b ((uint16_t)0x0700)
+#define SPI_DataSize_9b ((uint16_t)0x0800)
+#define SPI_DataSize_10b ((uint16_t)0x0900)
+#define SPI_DataSize_11b ((uint16_t)0x0A00)
+#define SPI_DataSize_12b ((uint16_t)0x0B00)
+#define SPI_DataSize_13b ((uint16_t)0x0C00)
+#define SPI_DataSize_14b ((uint16_t)0x0D00)
+#define SPI_DataSize_15b ((uint16_t)0x0E00)
+#define SPI_DataSize_16b ((uint16_t)0x0F00)
+#define IS_SPI_DATA_SIZE(SIZE) (((SIZE) == SPI_DataSize_4b) || \
+ ((SIZE) == SPI_DataSize_5b) || \
+ ((SIZE) == SPI_DataSize_6b) || \
+ ((SIZE) == SPI_DataSize_7b) || \
+ ((SIZE) == SPI_DataSize_8b) || \
+ ((SIZE) == SPI_DataSize_9b) || \
+ ((SIZE) == SPI_DataSize_10b) || \
+ ((SIZE) == SPI_DataSize_11b) || \
+ ((SIZE) == SPI_DataSize_12b) || \
+ ((SIZE) == SPI_DataSize_13b) || \
+ ((SIZE) == SPI_DataSize_14b) || \
+ ((SIZE) == SPI_DataSize_15b) || \
+ ((SIZE) == SPI_DataSize_16b))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_CRC_length
+ * @{
+ */
+
+#define SPI_CRCLength_8b ((uint16_t)0x0000)
+#define SPI_CRCLength_16b SPI_CR1_CRCL
+#define IS_SPI_CRC_LENGTH(LENGTH) (((LENGTH) == SPI_CRCLength_8b) || \
+ ((LENGTH) == SPI_CRCLength_16b))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_Clock_Polarity
+ * @{
+ */
+
+#define SPI_CPOL_Low ((uint16_t)0x0000)
+#define SPI_CPOL_High SPI_CR1_CPOL
+#define IS_SPI_CPOL(CPOL) (((CPOL) == SPI_CPOL_Low) || \
+ ((CPOL) == SPI_CPOL_High))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_Clock_Phase
+ * @{
+ */
+
+#define SPI_CPHA_1Edge ((uint16_t)0x0000)
+#define SPI_CPHA_2Edge SPI_CR1_CPHA
+#define IS_SPI_CPHA(CPHA) (((CPHA) == SPI_CPHA_1Edge) || \
+ ((CPHA) == SPI_CPHA_2Edge))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_Slave_Select_management
+ * @{
+ */
+
+#define SPI_NSS_Soft SPI_CR1_SSM
+#define SPI_NSS_Hard ((uint16_t)0x0000)
+#define IS_SPI_NSS(NSS) (((NSS) == SPI_NSS_Soft) || \
+ ((NSS) == SPI_NSS_Hard))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_BaudRate_Prescaler
+ * @{
+ */
+
+#define SPI_BaudRatePrescaler_2 ((uint16_t)0x0000)
+#define SPI_BaudRatePrescaler_4 ((uint16_t)0x0008)
+#define SPI_BaudRatePrescaler_8 ((uint16_t)0x0010)
+#define SPI_BaudRatePrescaler_16 ((uint16_t)0x0018)
+#define SPI_BaudRatePrescaler_32 ((uint16_t)0x0020)
+#define SPI_BaudRatePrescaler_64 ((uint16_t)0x0028)
+#define SPI_BaudRatePrescaler_128 ((uint16_t)0x0030)
+#define SPI_BaudRatePrescaler_256 ((uint16_t)0x0038)
+#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))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_MSB_LSB_transmission
+ * @{
+ */
+
+#define SPI_FirstBit_MSB ((uint16_t)0x0000)
+#define SPI_FirstBit_LSB SPI_CR1_LSBFIRST
+#define IS_SPI_FIRST_BIT(BIT) (((BIT) == SPI_FirstBit_MSB) || \
+ ((BIT) == SPI_FirstBit_LSB))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_I2S_Mode
+ * @{
+ */
+
+#define I2S_Mode_SlaveTx ((uint16_t)0x0000)
+#define I2S_Mode_SlaveRx ((uint16_t)0x0100)
+#define I2S_Mode_MasterTx ((uint16_t)0x0200)
+#define I2S_Mode_MasterRx ((uint16_t)0x0300)
+#define IS_I2S_MODE(MODE) (((MODE) == I2S_Mode_SlaveTx) || \
+ ((MODE) == I2S_Mode_SlaveRx) || \
+ ((MODE) == I2S_Mode_MasterTx)|| \
+ ((MODE) == I2S_Mode_MasterRx))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_I2S_Standard
+ * @{
+ */
+
+#define I2S_Standard_Phillips ((uint16_t)0x0000)
+#define I2S_Standard_MSB ((uint16_t)0x0010)
+#define I2S_Standard_LSB ((uint16_t)0x0020)
+#define I2S_Standard_PCMShort ((uint16_t)0x0030)
+#define I2S_Standard_PCMLong ((uint16_t)0x00B0)
+#define IS_I2S_STANDARD(STANDARD) (((STANDARD) == I2S_Standard_Phillips) || \
+ ((STANDARD) == I2S_Standard_MSB) || \
+ ((STANDARD) == I2S_Standard_LSB) || \
+ ((STANDARD) == I2S_Standard_PCMShort) || \
+ ((STANDARD) == I2S_Standard_PCMLong))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_I2S_Data_Format
+ * @{
+ */
+
+#define I2S_DataFormat_16b ((uint16_t)0x0000)
+#define I2S_DataFormat_16bextended ((uint16_t)0x0001)
+#define I2S_DataFormat_24b ((uint16_t)0x0003)
+#define I2S_DataFormat_32b ((uint16_t)0x0005)
+#define IS_I2S_DATA_FORMAT(FORMAT) (((FORMAT) == I2S_DataFormat_16b) || \
+ ((FORMAT) == I2S_DataFormat_16bextended) || \
+ ((FORMAT) == I2S_DataFormat_24b) || \
+ ((FORMAT) == I2S_DataFormat_32b))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_I2S_MCLK_Output
+ * @{
+ */
+
+#define I2S_MCLKOutput_Enable SPI_I2SPR_MCKOE
+#define I2S_MCLKOutput_Disable ((uint16_t)0x0000)
+#define IS_I2S_MCLK_OUTPUT(OUTPUT) (((OUTPUT) == I2S_MCLKOutput_Enable) || \
+ ((OUTPUT) == I2S_MCLKOutput_Disable))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_I2S_Audio_Frequency
+ * @{
+ */
+
+#define I2S_AudioFreq_192k ((uint32_t)192000)
+#define I2S_AudioFreq_96k ((uint32_t)96000)
+#define I2S_AudioFreq_48k ((uint32_t)48000)
+#define I2S_AudioFreq_44k ((uint32_t)44100)
+#define I2S_AudioFreq_32k ((uint32_t)32000)
+#define I2S_AudioFreq_22k ((uint32_t)22050)
+#define I2S_AudioFreq_16k ((uint32_t)16000)
+#define I2S_AudioFreq_11k ((uint32_t)11025)
+#define I2S_AudioFreq_8k ((uint32_t)8000)
+#define I2S_AudioFreq_Default ((uint32_t)2)
+
+#define IS_I2S_AUDIO_FREQ(FREQ) ((((FREQ) >= I2S_AudioFreq_8k) && \
+ ((FREQ) <= I2S_AudioFreq_192k)) || \
+ ((FREQ) == I2S_AudioFreq_Default))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_I2S_Clock_Polarity
+ * @{
+ */
+
+#define I2S_CPOL_Low ((uint16_t)0x0000)
+#define I2S_CPOL_High SPI_I2SCFGR_CKPOL
+#define IS_I2S_CPOL(CPOL) (((CPOL) == I2S_CPOL_Low) || \
+ ((CPOL) == I2S_CPOL_High))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_FIFO_reception_threshold
+ * @{
+ */
+
+#define SPI_RxFIFOThreshold_HF ((uint16_t)0x0000)
+#define SPI_RxFIFOThreshold_QF SPI_CR2_FRXTH
+#define IS_SPI_RX_FIFO_THRESHOLD(THRESHOLD) (((THRESHOLD) == SPI_RxFIFOThreshold_HF) || \
+ ((THRESHOLD) == SPI_RxFIFOThreshold_QF))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_I2S_DMA_transfer_requests
+ * @{
+ */
+
+#define SPI_I2S_DMAReq_Tx SPI_CR2_TXDMAEN
+#define SPI_I2S_DMAReq_Rx SPI_CR2_RXDMAEN
+#define IS_SPI_I2S_DMA_REQ(REQ) ((((REQ) & (uint16_t)0xFFFC) == 0x00) && ((REQ) != 0x00))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_last_DMA_transfers
+ * @{
+ */
+
+#define SPI_LastDMATransfer_TxEvenRxEven ((uint16_t)0x0000)
+#define SPI_LastDMATransfer_TxOddRxEven ((uint16_t)0x4000)
+#define SPI_LastDMATransfer_TxEvenRxOdd ((uint16_t)0x2000)
+#define SPI_LastDMATransfer_TxOddRxOdd ((uint16_t)0x6000)
+#define IS_SPI_LAST_DMA_TRANSFER(TRANSFER) (((TRANSFER) == SPI_LastDMATransfer_TxEvenRxEven) || \
+ ((TRANSFER) == SPI_LastDMATransfer_TxOddRxEven) || \
+ ((TRANSFER) == SPI_LastDMATransfer_TxEvenRxOdd) || \
+ ((TRANSFER) == SPI_LastDMATransfer_TxOddRxOdd))
+/**
+ * @}
+ */
+/** @defgroup SPI_NSS_internal_software_management
+ * @{
+ */
+
+#define SPI_NSSInternalSoft_Set SPI_CR1_SSI
+#define SPI_NSSInternalSoft_Reset ((uint16_t)0xFEFF)
+#define IS_SPI_NSS_INTERNAL(INTERNAL) (((INTERNAL) == SPI_NSSInternalSoft_Set) || \
+ ((INTERNAL) == SPI_NSSInternalSoft_Reset))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_CRC_Transmit_Receive
+ * @{
+ */
+
+#define SPI_CRC_Tx ((uint8_t)0x00)
+#define SPI_CRC_Rx ((uint8_t)0x01)
+#define IS_SPI_CRC(CRC) (((CRC) == SPI_CRC_Tx) || ((CRC) == SPI_CRC_Rx))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_direction_transmit_receive
+ * @{
+ */
+
+#define SPI_Direction_Rx ((uint16_t)0xBFFF)
+#define SPI_Direction_Tx ((uint16_t)0x4000)
+#define IS_SPI_DIRECTION(DIRECTION) (((DIRECTION) == SPI_Direction_Rx) || \
+ ((DIRECTION) == SPI_Direction_Tx))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_I2S_interrupts_definition
+ * @{
+ */
+
+#define SPI_I2S_IT_TXE ((uint8_t)0x71)
+#define SPI_I2S_IT_RXNE ((uint8_t)0x60)
+#define SPI_I2S_IT_ERR ((uint8_t)0x50)
+
+#define IS_SPI_I2S_CONFIG_IT(IT) (((IT) == SPI_I2S_IT_TXE) || \
+ ((IT) == SPI_I2S_IT_RXNE) || \
+ ((IT) == SPI_I2S_IT_ERR))
+
+#define I2S_IT_UDR ((uint8_t)0x53)
+#define SPI_IT_MODF ((uint8_t)0x55)
+#define SPI_I2S_IT_OVR ((uint8_t)0x56)
+#define SPI_I2S_IT_FRE ((uint8_t)0x58)
+
+#define IS_SPI_I2S_GET_IT(IT) (((IT) == SPI_I2S_IT_RXNE) || ((IT) == SPI_I2S_IT_TXE) || \
+ ((IT) == SPI_I2S_IT_OVR) || ((IT) == SPI_IT_MODF) || \
+ ((IT) == SPI_I2S_IT_FRE)|| ((IT) == I2S_IT_UDR))
+/**
+ * @}
+ */
+
+
+/** @defgroup SPI_transmission_fifo_status_level
+ * @{
+ */
+
+#define SPI_TransmissionFIFOStatus_Empty ((uint16_t)0x0000)
+#define SPI_TransmissionFIFOStatus_1QuarterFull ((uint16_t)0x0800)
+#define SPI_TransmissionFIFOStatus_HalfFull ((uint16_t)0x1000)
+#define SPI_TransmissionFIFOStatus_Full ((uint16_t)0x1800)
+
+/**
+ * @}
+ */
+
+/** @defgroup SPI_reception_fifo_status_level
+ * @{
+ */
+#define SPI_ReceptionFIFOStatus_Empty ((uint16_t)0x0000)
+#define SPI_ReceptionFIFOStatus_1QuarterFull ((uint16_t)0x0200)
+#define SPI_ReceptionFIFOStatus_HalfFull ((uint16_t)0x0400)
+#define SPI_ReceptionFIFOStatus_Full ((uint16_t)0x0600)
+
+/**
+ * @}
+ */
+
+
+/** @defgroup SPI_I2S_flags_definition
+ * @{
+ */
+
+#define SPI_I2S_FLAG_RXNE SPI_SR_RXNE
+#define SPI_I2S_FLAG_TXE SPI_SR_TXE
+#define I2S_FLAG_CHSIDE SPI_SR_CHSIDE
+#define I2S_FLAG_UDR SPI_SR_UDR
+#define SPI_FLAG_CRCERR SPI_SR_CRCERR
+#define SPI_FLAG_MODF SPI_SR_MODF
+#define SPI_I2S_FLAG_OVR SPI_SR_OVR
+#define SPI_I2S_FLAG_BSY SPI_SR_BSY
+#define SPI_I2S_FLAG_FRE SPI_SR_FRE
+
+
+
+#define IS_SPI_CLEAR_FLAG(FLAG) (((FLAG) == SPI_FLAG_CRCERR))
+#define IS_SPI_I2S_GET_FLAG(FLAG) (((FLAG) == SPI_I2S_FLAG_BSY) || ((FLAG) == SPI_I2S_FLAG_OVR) || \
+ ((FLAG) == SPI_FLAG_MODF) || ((FLAG) == SPI_FLAG_CRCERR) || \
+ ((FLAG) == SPI_I2S_FLAG_TXE) || ((FLAG) == SPI_I2S_FLAG_RXNE)|| \
+ ((FLAG) == SPI_I2S_FLAG_FRE)|| ((FLAG) == I2S_FLAG_CHSIDE)|| \
+ ((FLAG) == I2S_FLAG_UDR))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_CRC_polynomial
+ * @{
+ */
+
+#define IS_SPI_CRC_POLYNOMIAL(POLYNOMIAL) ((POLYNOMIAL) >= 0x1)
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+
+/* Initialization and Configuration functions *********************************/
+void SPI_I2S_DeInit(SPI_TypeDef* SPIx);
+void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct);
+void I2S_Init(SPI_TypeDef* SPIx, I2S_InitTypeDef* I2S_InitStruct);
+void SPI_StructInit(SPI_InitTypeDef* SPI_InitStruct);
+void I2S_StructInit(I2S_InitTypeDef* I2S_InitStruct);
+void SPI_TIModeCmd(SPI_TypeDef* SPIx, FunctionalState NewState);
+void SPI_NSSPulseModeCmd(SPI_TypeDef* SPIx, FunctionalState NewState);
+void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState);
+void I2S_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState);
+void SPI_DataSizeConfig(SPI_TypeDef* SPIx, uint16_t SPI_DataSize);
+void SPI_RxFIFOThresholdConfig(SPI_TypeDef* SPIx, uint16_t SPI_RxFIFOThreshold);
+void SPI_BiDirectionalLineConfig(SPI_TypeDef* SPIx, uint16_t SPI_Direction);
+void SPI_NSSInternalSoftwareConfig(SPI_TypeDef* SPIx, uint16_t SPI_NSSInternalSoft);
+void SPI_SSOutputCmd(SPI_TypeDef* SPIx, FunctionalState NewState);
+
+/* Data transfers functions ***************************************************/
+void SPI_SendData8(SPI_TypeDef* SPIx, uint8_t Data);
+void SPI_I2S_SendData16(SPI_TypeDef* SPIx, uint16_t Data);
+uint8_t SPI_ReceiveData8(SPI_TypeDef* SPIx);
+uint16_t SPI_I2S_ReceiveData16(SPI_TypeDef* SPIx);
+
+/* Hardware CRC Calculation functions *****************************************/
+void SPI_CRCLengthConfig(SPI_TypeDef* SPIx, uint16_t SPI_CRCLength);
+void SPI_CalculateCRC(SPI_TypeDef* SPIx, FunctionalState NewState);
+void SPI_TransmitCRC(SPI_TypeDef* SPIx);
+uint16_t SPI_GetCRC(SPI_TypeDef* SPIx, uint8_t SPI_CRC);
+uint16_t SPI_GetCRCPolynomial(SPI_TypeDef* SPIx);
+
+
+
+/* Interrupts and flags management functions **********************************/
+void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState);
+uint16_t SPI_GetTransmissionFIFOStatus(SPI_TypeDef* SPIx);
+uint16_t SPI_GetReceptionFIFOStatus(SPI_TypeDef* SPIx);
+FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);
+void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);
+ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__HK32F030M_SPI_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_syscfg.h b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_syscfg.h
new file mode 100644
index 0000000..5c18bcd
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_syscfg.h
@@ -0,0 +1,130 @@
+/**
+ ******************************************************************************
+ * @file hk32f030m_syscfg.h
+ * @author Rakan.z
+ * @version V1.0
+ * @brief API file of PWR module
+ * @changelist
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __HK32F030M_SYSCFG_H
+#define __HK32F030M_SYSCFG_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "hk32f030m.h"
+
+
+/** @addtogroup SYSCFG
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup SYSCFG_EXTI_Port_Sources
+ * @{
+ */
+#define EXTI_PortSourceGPIOA ((uint8_t)0x00)
+#define EXTI_PortSourceGPIOB ((uint8_t)0x01)
+#define EXTI_PortSourceGPIOC ((uint8_t)0x02)
+#define EXTI_PortSourceGPIOD ((uint8_t)0x03)
+
+#define IS_EXTI_PORT_SOURCE(PORTSOURCE) (((PORTSOURCE) == EXTI_PortSourceGPIOA) || \
+ ((PORTSOURCE) == EXTI_PortSourceGPIOB) || \
+ ((PORTSOURCE) == EXTI_PortSourceGPIOC) || \
+ ((PORTSOURCE) == EXTI_PortSourceGPIOD) )
+
+/**
+ * @}
+ */
+
+
+/** @defgroup SYSCFG_EXTI_Pin_Sources
+ * @{
+ */
+#define EXTI_PinSource0 ((uint8_t)0x00)
+#define EXTI_PinSource1 ((uint8_t)0x01)
+#define EXTI_PinSource2 ((uint8_t)0x02)
+#define EXTI_PinSource3 ((uint8_t)0x03)
+#define EXTI_PinSource4 ((uint8_t)0x04)
+#define EXTI_PinSource5 ((uint8_t)0x05)
+#define EXTI_PinSource6 ((uint8_t)0x06)
+#define EXTI_PinSource7 ((uint8_t)0x07)
+#define EXTI_PinSource8 ((uint8_t)0x08)
+#define EXTI_PinSource9 ((uint8_t)0x09)
+#define EXTI_PinSource10 ((uint8_t)0x0A)
+#define EXTI_PinSource11 ((uint8_t)0x0B)
+#define EXTI_PinSource12 ((uint8_t)0x0C)
+#define EXTI_PinSource13 ((uint8_t)0x0D)
+#define EXTI_PinSource14 ((uint8_t)0x0E)
+#define EXTI_PinSource15 ((uint8_t)0x0F)
+#define IS_EXTI_PIN_SOURCE(PINSOURCE) (((PINSOURCE) == EXTI_PinSource0) || \
+ ((PINSOURCE) == EXTI_PinSource1) || \
+ ((PINSOURCE) == EXTI_PinSource2) || \
+ ((PINSOURCE) == EXTI_PinSource3) || \
+ ((PINSOURCE) == EXTI_PinSource4) || \
+ ((PINSOURCE) == EXTI_PinSource5) || \
+ ((PINSOURCE) == EXTI_PinSource6) || \
+ ((PINSOURCE) == EXTI_PinSource7) || \
+ ((PINSOURCE) == EXTI_PinSource8) || \
+ ((PINSOURCE) == EXTI_PinSource9) || \
+ ((PINSOURCE) == EXTI_PinSource10) || \
+ ((PINSOURCE) == EXTI_PinSource11) || \
+ ((PINSOURCE) == EXTI_PinSource12) || \
+ ((PINSOURCE) == EXTI_PinSource13) || \
+ ((PINSOURCE) == EXTI_PinSource14) || \
+ ((PINSOURCE) == EXTI_PinSource15))
+
+/**
+ * SYSCFG memoryremap
+ * @}
+ */
+#define SYSCFG_MemoryRemap_Flash ((uint8_t)0x00)
+#define SYSCFG_MemoryRemap_SRAM ((uint8_t)0x03)
+
+#define IS_SYSCFG_MEMORY_REMAP_CONFING(REMAP) (((REMAP) == SYSCFG_MemoryRemap_Flash) || ((REMAP) == SYSCFG_MemoryRemap_SRAM))
+/**
+ * SYSCFG Cortex-M0 LOCKUP_LOCK
+ * @}
+*/
+
+#define SYSCFG_Lockup_TIM1Break_OFF ((uint8_t)0x00)
+#define SYSCFG_Lockup_TIM1Break_ON ((uint8_t)0x01)
+
+#define IS_SYSCFG_LOCKUP_TIM1BREAK_ONOFF(ONOFF) (((ONOFF) == SYSCFG_Lockup_TIM1Break_OFF) || \
+ ((ONOFF) == SYSCFG_Lockup_TIM1Break_ON) )
+
+/*
+*SYSYCFG CFGR1 registers mask
+*/
+#define MEM_REMAP_MASK ((uint32_t)0xFFFFFFC)
+#define MEM_LOCKUP_OUT_MASK ((uint32_t)0x7FFFFFF)
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+void SYSCFG_DeInit(void);
+void SYSCFG_EXTILineConfig(uint8_t EXTI_PortSourceGPIOx, uint8_t EXTI_PinSourcex);
+void SYSCFG_MemoryRemapConfig(uint8_t SYSCFG_MemoryRemap);
+void SYSCFG_Lockup_Tim1BreakConfig(uint8_t Lockup_lockOnOff);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__HK32F030M_SYSCFG_H */
+
+/**
+ * @}
+ */
+
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_tim.h b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_tim.h
new file mode 100644
index 0000000..b55f493
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_tim.h
@@ -0,0 +1,967 @@
+/**
+ ******************************************************************************
+ * @file hk32f030m_tim.h
+ * @version V1.0.0
+ * @date 2019-12-25
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __HK32F030M_TIM_H
+#define __HK32F030M_TIM_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "hk32f030m.h"
+
+/** @addtogroup TIM
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+
+/**
+ * @brief TIM Time Base Init structure definition
+ * @note This sturcture is used with all TIMx.
+ */
+
+typedef struct
+{
+ uint16_t TIM_Prescaler; /*!< Specifies the prescaler value used to divide the TIM clock.
+ This parameter can be a number between 0x0000 and 0xFFFF */
+
+ uint16_t TIM_CounterMode; /*!< Specifies the counter mode.
+ This parameter can be a value of @ref TIM_Counter_Mode */
+
+ uint32_t TIM_Period; /*!< Specifies the period value to be loaded into the active
+ Auto-Reload Register at the next update event.
+ This parameter must be a number between 0x0000 and 0xFFFF. */
+
+ uint16_t TIM_ClockDivision; /*!< Specifies the clock division.
+ This parameter can be a value of @ref TIM_Clock_Division_CKD */
+
+ uint8_t TIM_RepetitionCounter; /*!< Specifies the repetition counter value. Each time the RCR downcounter
+ reaches zero, an update event is generated and counting restarts
+ from the RCR value (N).
+ This means in PWM mode that (N+1) corresponds to:
+ - the number of PWM periods in edge-aligned mode
+ - the number of half PWM period in center-aligned mode
+ This parameter must be a number between 0x00 and 0xFF.
+ @note This parameter is valid only for TIM1. */
+} TIM_TimeBaseInitTypeDef;
+
+/**
+ * @brief TIM Output Compare Init structure definition
+ */
+
+typedef struct
+{
+ uint16_t TIM_OCMode; /*!< Specifies the TIM mode.
+ This parameter can be a value of @ref TIM_Output_Compare_and_PWM_modes */
+
+ uint16_t TIM_OutputState; /*!< Specifies the TIM Output Compare state.
+ This parameter can be a value of @ref TIM_Output_Compare_state */
+
+ uint16_t TIM_OutputNState; /*!< Specifies the TIM complementary Output Compare state.
+ This parameter can be a value of @ref TIM_Output_Compare_N_state
+ @note This parameter is valid only for TIM1. */
+
+ uint32_t TIM_Pulse; /*!< Specifies the pulse value to be loaded into the Capture Compare Register.
+ This parameter can be a number between 0x0000 and 0xFFFF ( or 0xFFFFFFFF
+ for TIM2) */
+
+ uint16_t TIM_OCPolarity; /*!< Specifies the output polarity.
+ This parameter can be a value of @ref TIM_Output_Compare_Polarity */
+
+ uint16_t TIM_OCNPolarity; /*!< Specifies the complementary output polarity.
+ This parameter can be a value of @ref TIM_Output_Compare_N_Polarity
+ @note This parameter is valid only for TIM1. */
+
+ uint16_t TIM_OCIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state.
+ This parameter can be a value of @ref TIM_Output_Compare_Idle_State
+ @note This parameter is valid only for TIM1. */
+
+ uint16_t TIM_OCNIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state.
+ This parameter can be a value of @ref TIM_Output_Compare_N_Idle_State
+ @note This parameter is valid only for TIM1. */
+} TIM_OCInitTypeDef;
+
+/**
+ * @brief TIM Input Capture Init structure definition
+ */
+
+typedef struct
+{
+
+ uint16_t TIM_Channel; /*!< Specifies the TIM channel.
+ This parameter can be a value of @ref TIM_Channel */
+
+ uint16_t TIM_ICPolarity; /*!< Specifies the active edge of the input signal.
+ This parameter can be a value of @ref TIM_Input_Capture_Polarity */
+
+ uint16_t TIM_ICSelection; /*!< Specifies the input.
+ This parameter can be a value of @ref TIM_Input_Capture_Selection */
+
+ uint16_t TIM_ICPrescaler; /*!< Specifies the Input Capture Prescaler.
+ This parameter can be a value of @ref TIM_Input_Capture_Prescaler */
+
+ uint16_t TIM_ICFilter; /*!< Specifies the input capture filter.
+ This parameter can be a number between 0x0 and 0xF */
+} TIM_ICInitTypeDef;
+
+/**
+ * @brief TIM_BDTR structure definition
+ * @note This sturcture is used only with TIM1.
+ */
+
+typedef struct
+{
+
+ uint16_t TIM_OSSRState; /*!< Specifies the Off-State selection used in Run mode.
+ This parameter can be a value of @ref TIM_OSSR_Off_State_Selection_for_Run_mode_state */
+
+ uint16_t TIM_OSSIState; /*!< Specifies the Off-State used in Idle state.
+ This parameter can be a value of @ref TIM_OSSI_Off_State_Selection_for_Idle_mode_state */
+
+ uint16_t TIM_LOCKLevel; /*!< Specifies the LOCK level parameters.
+ This parameter can be a value of @ref TIM_Lock_level */
+
+ uint16_t TIM_DeadTime; /*!< Specifies the delay time between the switching-off and the
+ switching-on of the outputs.
+ This parameter can be a number between 0x00 and 0xFF */
+
+ uint16_t TIM_Break; /*!< Specifies whether the TIM Break input is enabled or not.
+ This parameter can be a value of @ref TIM_Break_Input_enable_disable */
+
+ uint16_t TIM_BreakPolarity; /*!< Specifies the TIM Break Input pin polarity.
+ This parameter can be a value of @ref TIM_Break_Polarity */
+
+ uint16_t TIM_AutomaticOutput; /*!< Specifies whether the TIM Automatic Output feature is enabled or not.
+ This parameter can be a value of @ref TIM_AOE_Bit_Set_Reset */
+} TIM_BDTRInitTypeDef;
+
+/**
+ * @brief TIM Input Capture Init structure definition
+ */
+
+/* Exported constants --------------------------------------------------------*/
+
+
+/** @defgroup TIM_Exported_constants
+ * @{
+ */
+
+#define IS_TIM_ALL_PERIPH(PERIPH) (((PERIPH) == TIM1) || \
+ ((PERIPH) == TIM2) || \
+ ((PERIPH) == TIM6))
+
+
+/* LIST1: TIM 1 */
+#define IS_TIM_LIST1_PERIPH(PERIPH) ((PERIPH) == TIM1)
+
+/* LIST2: TIM 1 */
+#define IS_TIM_LIST2_PERIPH(PERIPH) (((PERIPH) == TIM1))
+
+/* LIST3: TIM 1, 2 */
+#define IS_TIM_LIST3_PERIPH(PERIPH) (((PERIPH) == TIM1) || \
+ ((PERIPH) == TIM2))
+
+/* LIST4: TIM 1, 2 */
+#define IS_TIM_LIST4_PERIPH(PERIPH) (((PERIPH) == TIM1) || \
+ ((PERIPH) == TIM2))
+
+/* LIST5: TIM 1, 2 */
+#define IS_TIM_LIST5_PERIPH(PERIPH) (((PERIPH) == TIM1) || \
+ ((PERIPH) == TIM2))
+
+/* LIST6: TIM 1, 2 */
+#define IS_TIM_LIST6_PERIPH(PERIPH) (((PERIPH) == TIM1) || \
+ ((PERIPH) == TIM2))
+
+/* LIST7: TIM 1, 2, 6 */
+#define IS_TIM_LIST7_PERIPH(PERIPH) (((PERIPH) == TIM1) || \
+ ((PERIPH) == TIM2) || \
+ ((PERIPH) == TIM6))
+
+/* LIST8: TIM 1, 2 */
+#define IS_TIM_LIST8_PERIPH(PERIPH) (((PERIPH) == TIM1) || \
+ ((PERIPH) == TIM2))
+
+/* LIST9: TIM 1, 2, 6 */
+#define IS_TIM_LIST9_PERIPH(PERIPH) (((PERIPH) == TIM1) || \
+ ((PERIPH) == TIM2) || \
+ ((PERIPH) == TIM6))
+
+/* LIST10: TIM 1, 2, 6 */
+#define IS_TIM_LIST10_PERIPH(PERIPH) (((PERIPH) == TIM1) || \
+ ((PERIPH) == TIM2) || \
+ ((PERIPH) == TIM6))
+
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Output_Compare_and_PWM_modes
+ * @{
+ */
+
+#define TIM_OCMode_Timing ((uint16_t)0x0000)
+#define TIM_OCMode_Active ((uint16_t)0x0010)
+#define TIM_OCMode_Inactive ((uint16_t)0x0020)
+#define TIM_OCMode_Toggle ((uint16_t)0x0030)
+#define TIM_OCMode_PWM1 ((uint16_t)0x0060)
+#define TIM_OCMode_PWM2 ((uint16_t)0x0070)
+#define IS_TIM_OC_MODE(MODE) (((MODE) == TIM_OCMode_Timing) || \
+ ((MODE) == TIM_OCMode_Active) || \
+ ((MODE) == TIM_OCMode_Inactive) || \
+ ((MODE) == TIM_OCMode_Toggle)|| \
+ ((MODE) == TIM_OCMode_PWM1) || \
+ ((MODE) == TIM_OCMode_PWM2))
+#define IS_TIM_OCM(MODE) (((MODE) == TIM_OCMode_Timing) || \
+ ((MODE) == TIM_OCMode_Active) || \
+ ((MODE) == TIM_OCMode_Inactive) || \
+ ((MODE) == TIM_OCMode_Toggle)|| \
+ ((MODE) == TIM_OCMode_PWM1) || \
+ ((MODE) == TIM_OCMode_PWM2) || \
+ ((MODE) == TIM_ForcedAction_Active) || \
+ ((MODE) == TIM_ForcedAction_InActive))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_One_Pulse_Mode
+ * @{
+ */
+
+#define TIM_OPMode_Single ((uint16_t)0x0008)
+#define TIM_OPMode_Repetitive ((uint16_t)0x0000)
+#define IS_TIM_OPM_MODE(MODE) (((MODE) == TIM_OPMode_Single) || \
+ ((MODE) == TIM_OPMode_Repetitive))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Channel
+ * @{
+ */
+
+#define TIM_Channel_1 ((uint16_t)0x0000)
+#define TIM_Channel_2 ((uint16_t)0x0004)
+#define TIM_Channel_3 ((uint16_t)0x0008)
+#define TIM_Channel_4 ((uint16_t)0x000C)
+
+#define IS_TIM_CHANNEL(CHANNEL) (((CHANNEL) == TIM_Channel_1) || \
+ ((CHANNEL) == TIM_Channel_2) || \
+ ((CHANNEL) == TIM_Channel_3) || \
+ ((CHANNEL) == TIM_Channel_4))
+#define IS_TIM_COMPLEMENTARY_CHANNEL(CHANNEL) (((CHANNEL) == TIM_Channel_1) || \
+ ((CHANNEL) == TIM_Channel_2) || \
+ ((CHANNEL) == TIM_Channel_3))
+#define IS_TIM_PWMI_CHANNEL(CHANNEL) (((CHANNEL) == TIM_Channel_1) || \
+ ((CHANNEL) == TIM_Channel_2))
+
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Clock_Division_CKD
+ * @{
+ */
+
+#define TIM_CKD_DIV1 ((uint16_t)0x0000)
+#define TIM_CKD_DIV2 ((uint16_t)0x0100)
+#define TIM_CKD_DIV4 ((uint16_t)0x0200)
+#define IS_TIM_CKD_DIV(DIV) (((DIV) == TIM_CKD_DIV1) || \
+ ((DIV) == TIM_CKD_DIV2) || \
+ ((DIV) == TIM_CKD_DIV4))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Counter_Mode
+ * @{
+ */
+
+#define TIM_CounterMode_Up ((uint16_t)0x0000)
+#define TIM_CounterMode_Down ((uint16_t)0x0010)
+#define TIM_CounterMode_CenterAligned1 ((uint16_t)0x0020)
+#define TIM_CounterMode_CenterAligned2 ((uint16_t)0x0040)
+#define TIM_CounterMode_CenterAligned3 ((uint16_t)0x0060)
+#define IS_TIM_COUNTER_MODE(MODE) (((MODE) == TIM_CounterMode_Up) || \
+ ((MODE) == TIM_CounterMode_Down) || \
+ ((MODE) == TIM_CounterMode_CenterAligned1) || \
+ ((MODE) == TIM_CounterMode_CenterAligned2) || \
+ ((MODE) == TIM_CounterMode_CenterAligned3))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Output_Compare_Polarity
+ * @{
+ */
+
+#define TIM_OCPolarity_High ((uint16_t)0x0000)
+#define TIM_OCPolarity_Low ((uint16_t)0x0002)
+#define IS_TIM_OC_POLARITY(POLARITY) (((POLARITY) == TIM_OCPolarity_High) || \
+ ((POLARITY) == TIM_OCPolarity_Low))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Output_Compare_N_Polarity
+ * @{
+ */
+
+#define TIM_OCNPolarity_High ((uint16_t)0x0000)
+#define TIM_OCNPolarity_Low ((uint16_t)0x0008)
+#define IS_TIM_OCN_POLARITY(POLARITY) (((POLARITY) == TIM_OCNPolarity_High) || \
+ ((POLARITY) == TIM_OCNPolarity_Low))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Output_Compare_state
+ * @{
+ */
+
+#define TIM_OutputState_Disable ((uint16_t)0x0000)
+#define TIM_OutputState_Enable ((uint16_t)0x0001)
+#define IS_TIM_OUTPUT_STATE(STATE) (((STATE) == TIM_OutputState_Disable) || \
+ ((STATE) == TIM_OutputState_Enable))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Output_Compare_N_state
+ * @{
+ */
+
+#define TIM_OutputNState_Disable ((uint16_t)0x0000)
+#define TIM_OutputNState_Enable ((uint16_t)0x0004)
+#define IS_TIM_OUTPUTN_STATE(STATE) (((STATE) == TIM_OutputNState_Disable) || \
+ ((STATE) == TIM_OutputNState_Enable))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Capture_Compare_state
+ * @{
+ */
+
+#define TIM_CCx_Enable ((uint16_t)0x0001)
+#define TIM_CCx_Disable ((uint16_t)0x0000)
+#define IS_TIM_CCX(CCX) (((CCX) == TIM_CCx_Enable) || \
+ ((CCX) == TIM_CCx_Disable))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Capture_Compare_N_state
+ * @{
+ */
+
+#define TIM_CCxN_Enable ((uint16_t)0x0004)
+#define TIM_CCxN_Disable ((uint16_t)0x0000)
+#define IS_TIM_CCXN(CCXN) (((CCXN) == TIM_CCxN_Enable) || \
+ ((CCXN) == TIM_CCxN_Disable))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Break_Input_enable_disable
+ * @{
+ */
+
+#define TIM_Break_Enable ((uint16_t)0x1000)
+#define TIM_Break_Disable ((uint16_t)0x0000)
+#define IS_TIM_BREAK_STATE(STATE) (((STATE) == TIM_Break_Enable) || \
+ ((STATE) == TIM_Break_Disable))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Break_Polarity
+ * @{
+ */
+
+#define TIM_BreakPolarity_Low ((uint16_t)0x0000)
+#define TIM_BreakPolarity_High ((uint16_t)0x2000)
+#define IS_TIM_BREAK_POLARITY(POLARITY) (((POLARITY) == TIM_BreakPolarity_Low) || \
+ ((POLARITY) == TIM_BreakPolarity_High))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_AOE_Bit_Set_Reset
+ * @{
+ */
+
+#define TIM_AutomaticOutput_Enable ((uint16_t)0x4000)
+#define TIM_AutomaticOutput_Disable ((uint16_t)0x0000)
+#define IS_TIM_AUTOMATIC_OUTPUT_STATE(STATE) (((STATE) == TIM_AutomaticOutput_Enable) || \
+ ((STATE) == TIM_AutomaticOutput_Disable))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Lock_level
+ * @{
+ */
+
+#define TIM_LOCKLevel_OFF ((uint16_t)0x0000)
+#define TIM_LOCKLevel_1 ((uint16_t)0x0100)
+#define TIM_LOCKLevel_2 ((uint16_t)0x0200)
+#define TIM_LOCKLevel_3 ((uint16_t)0x0300)
+#define IS_TIM_LOCK_LEVEL(LEVEL) (((LEVEL) == TIM_LOCKLevel_OFF) || \
+ ((LEVEL) == TIM_LOCKLevel_1) || \
+ ((LEVEL) == TIM_LOCKLevel_2) || \
+ ((LEVEL) == TIM_LOCKLevel_3))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_OSSI_Off_State_Selection_for_Idle_mode_state
+ * @{
+ */
+
+#define TIM_OSSIState_Enable ((uint16_t)0x0400)
+#define TIM_OSSIState_Disable ((uint16_t)0x0000)
+#define IS_TIM_OSSI_STATE(STATE) (((STATE) == TIM_OSSIState_Enable) || \
+ ((STATE) == TIM_OSSIState_Disable))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_OSSR_Off_State_Selection_for_Run_mode_state
+ * @{
+ */
+
+#define TIM_OSSRState_Enable ((uint16_t)0x0800)
+#define TIM_OSSRState_Disable ((uint16_t)0x0000)
+#define IS_TIM_OSSR_STATE(STATE) (((STATE) == TIM_OSSRState_Enable) || \
+ ((STATE) == TIM_OSSRState_Disable))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Output_Compare_Idle_State
+ * @{
+ */
+
+#define TIM_OCIdleState_Set ((uint16_t)0x0100)
+#define TIM_OCIdleState_Reset ((uint16_t)0x0000)
+#define IS_TIM_OCIDLE_STATE(STATE) (((STATE) == TIM_OCIdleState_Set) || \
+ ((STATE) == TIM_OCIdleState_Reset))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Output_Compare_N_Idle_State
+ * @{
+ */
+
+#define TIM_OCNIdleState_Set ((uint16_t)0x0200)
+#define TIM_OCNIdleState_Reset ((uint16_t)0x0000)
+#define IS_TIM_OCNIDLE_STATE(STATE) (((STATE) == TIM_OCNIdleState_Set) || \
+ ((STATE) == TIM_OCNIdleState_Reset))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Input_Capture_Polarity
+ * @{
+ */
+
+#define TIM_ICPolarity_Rising ((uint16_t)0x0000)
+#define TIM_ICPolarity_Falling ((uint16_t)0x0002)
+#define TIM_ICPolarity_BothEdge ((uint16_t)0x000A)
+#define IS_TIM_IC_POLARITY(POLARITY) (((POLARITY) == TIM_ICPolarity_Rising) || \
+ ((POLARITY) == TIM_ICPolarity_Falling)|| \
+ ((POLARITY) == TIM_ICPolarity_BothEdge))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Input_Capture_Selection
+ * @{
+ */
+
+#define TIM_ICSelection_DirectTI ((uint16_t)0x0001) /*!< TIM Input 1, 2, 3 or 4 is selected to be
+ connected to IC1, IC2, IC3 or IC4, respectively */
+#define TIM_ICSelection_IndirectTI ((uint16_t)0x0002) /*!< TIM Input 1, 2, 3 or 4 is selected to be
+ connected to IC2, IC1, IC4 or IC3, respectively. */
+#define TIM_ICSelection_TRC ((uint16_t)0x0003) /*!< TIM Input 1, 2, 3 or 4 is selected to be connected to TRC. */
+#define IS_TIM_IC_SELECTION(SELECTION) (((SELECTION) == TIM_ICSelection_DirectTI) || \
+ ((SELECTION) == TIM_ICSelection_IndirectTI) || \
+ ((SELECTION) == TIM_ICSelection_TRC))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Input_Capture_Prescaler
+ * @{
+ */
+
+#define TIM_ICPSC_DIV1 ((uint16_t)0x0000) /*!< Capture performed each time an edge is detected on the capture input. */
+#define TIM_ICPSC_DIV2 ((uint16_t)0x0004) /*!< Capture performed once every 2 events. */
+#define TIM_ICPSC_DIV4 ((uint16_t)0x0008) /*!< Capture performed once every 4 events. */
+#define TIM_ICPSC_DIV8 ((uint16_t)0x000C) /*!< Capture performed once every 8 events. */
+#define IS_TIM_IC_PRESCALER(PRESCALER) (((PRESCALER) == TIM_ICPSC_DIV1) || \
+ ((PRESCALER) == TIM_ICPSC_DIV2) || \
+ ((PRESCALER) == TIM_ICPSC_DIV4) || \
+ ((PRESCALER) == TIM_ICPSC_DIV8))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_interrupt_sources
+ * @{
+ */
+
+#define TIM_IT_Update ((uint16_t)0x0001)
+#define TIM_IT_CC1 ((uint16_t)0x0002)
+#define TIM_IT_CC2 ((uint16_t)0x0004)
+#define TIM_IT_CC3 ((uint16_t)0x0008)
+#define TIM_IT_CC4 ((uint16_t)0x0010)
+#define TIM_IT_COM ((uint16_t)0x0020)
+#define TIM_IT_Trigger ((uint16_t)0x0040)
+#define TIM_IT_Break ((uint16_t)0x0080)
+#define IS_TIM_IT(IT) ((((IT) & (uint16_t)0xFF00) == 0x0000) && ((IT) != 0x0000))
+
+#define IS_TIM_GET_IT(IT) (((IT) == TIM_IT_Update) || \
+ ((IT) == TIM_IT_CC1) || \
+ ((IT) == TIM_IT_CC2) || \
+ ((IT) == TIM_IT_CC3) || \
+ ((IT) == TIM_IT_CC4) || \
+ ((IT) == TIM_IT_COM) || \
+ ((IT) == TIM_IT_Trigger) || \
+ ((IT) == TIM_IT_Break))
+
+/**
+ * @}
+ */
+
+/** @defgroup TIM_External_Trigger_Prescaler
+ * @{
+ */
+
+#define TIM_ExtTRGPSC_OFF ((uint16_t)0x0000)
+#define TIM_ExtTRGPSC_DIV2 ((uint16_t)0x1000)
+#define TIM_ExtTRGPSC_DIV4 ((uint16_t)0x2000)
+#define TIM_ExtTRGPSC_DIV8 ((uint16_t)0x3000)
+#define IS_TIM_EXT_PRESCALER(PRESCALER) (((PRESCALER) == TIM_ExtTRGPSC_OFF) || \
+ ((PRESCALER) == TIM_ExtTRGPSC_DIV2) || \
+ ((PRESCALER) == TIM_ExtTRGPSC_DIV4) || \
+ ((PRESCALER) == TIM_ExtTRGPSC_DIV8))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Internal_Trigger_Selection
+ * @{
+ */
+
+#define TIM_TS_ITR0 ((uint16_t)0x0000)
+#define TIM_TS_ITR1 ((uint16_t)0x0010)
+#define TIM_TS_ITR2 ((uint16_t)0x0020)
+#define TIM_TS_ITR3 ((uint16_t)0x0030)
+#define TIM_TS_TI1F_ED ((uint16_t)0x0040)
+#define TIM_TS_TI1FP1 ((uint16_t)0x0050)
+#define TIM_TS_TI2FP2 ((uint16_t)0x0060)
+#define TIM_TS_ETRF ((uint16_t)0x0070)
+#define IS_TIM_TRIGGER_SELECTION(SELECTION) (((SELECTION) == TIM_TS_ITR0) || \
+ ((SELECTION) == TIM_TS_ITR1) || \
+ ((SELECTION) == TIM_TS_ITR2) || \
+ ((SELECTION) == TIM_TS_ITR3) || \
+ ((SELECTION) == TIM_TS_TI1F_ED) || \
+ ((SELECTION) == TIM_TS_TI1FP1) || \
+ ((SELECTION) == TIM_TS_TI2FP2) || \
+ ((SELECTION) == TIM_TS_ETRF))
+#define IS_TIM_INTERNAL_TRIGGER_SELECTION(SELECTION) (((SELECTION) == TIM_TS_ITR0) || \
+ ((SELECTION) == TIM_TS_ITR1) || \
+ ((SELECTION) == TIM_TS_ITR2) || \
+ ((SELECTION) == TIM_TS_ITR3))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_TIx_External_Clock_Source
+ * @{
+ */
+
+#define TIM_TIxExternalCLK1Source_TI1 ((uint16_t)0x0050)
+#define TIM_TIxExternalCLK1Source_TI2 ((uint16_t)0x0060)
+#define TIM_TIxExternalCLK1Source_TI1ED ((uint16_t)0x0040)
+
+/**
+ * @}
+ */
+
+/** @defgroup TIM_External_Trigger_Polarity
+ * @{
+ */
+#define TIM_ExtTRGPolarity_Inverted ((uint16_t)0x8000)
+#define TIM_ExtTRGPolarity_NonInverted ((uint16_t)0x0000)
+#define IS_TIM_EXT_POLARITY(POLARITY) (((POLARITY) == TIM_ExtTRGPolarity_Inverted) || \
+ ((POLARITY) == TIM_ExtTRGPolarity_NonInverted))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Prescaler_Reload_Mode
+ * @{
+ */
+
+#define TIM_PSCReloadMode_Update ((uint16_t)0x0000)
+#define TIM_PSCReloadMode_Immediate ((uint16_t)0x0001)
+#define IS_TIM_PRESCALER_RELOAD(RELOAD) (((RELOAD) == TIM_PSCReloadMode_Update) || \
+ ((RELOAD) == TIM_PSCReloadMode_Immediate))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Forced_Action
+ * @{
+ */
+
+#define TIM_ForcedAction_Active ((uint16_t)0x0050)
+#define TIM_ForcedAction_InActive ((uint16_t)0x0040)
+#define IS_TIM_FORCED_ACTION(ACTION) (((ACTION) == TIM_ForcedAction_Active) || \
+ ((ACTION) == TIM_ForcedAction_InActive))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Encoder_Mode
+ * @{
+ */
+
+#define TIM_EncoderMode_TI1 ((uint16_t)0x0001)
+#define TIM_EncoderMode_TI2 ((uint16_t)0x0002)
+#define TIM_EncoderMode_TI12 ((uint16_t)0x0003)
+#define IS_TIM_ENCODER_MODE(MODE) (((MODE) == TIM_EncoderMode_TI1) || \
+ ((MODE) == TIM_EncoderMode_TI2) || \
+ ((MODE) == TIM_EncoderMode_TI12))
+/**
+ * @}
+ */
+
+
+/** @defgroup TIM_Event_Source
+ * @{
+ */
+
+#define TIM_EventSource_Update ((uint16_t)0x0001)
+#define TIM_EventSource_CC1 ((uint16_t)0x0002)
+#define TIM_EventSource_CC2 ((uint16_t)0x0004)
+#define TIM_EventSource_CC3 ((uint16_t)0x0008)
+#define TIM_EventSource_CC4 ((uint16_t)0x0010)
+#define TIM_EventSource_COM ((uint16_t)0x0020)
+#define TIM_EventSource_Trigger ((uint16_t)0x0040)
+#define TIM_EventSource_Break ((uint16_t)0x0080)
+#define IS_TIM_EVENT_SOURCE(SOURCE) ((((SOURCE) & (uint16_t)0xFF00) == 0x0000) && ((SOURCE) != 0x0000))
+
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Update_Source
+ * @{
+ */
+
+#define TIM_UpdateSource_Global ((uint16_t)0x0000) /*!< Source of update is the counter overflow/underflow
+ or the setting of UG bit, or an update generation
+ through the slave mode controller. */
+#define TIM_UpdateSource_Regular ((uint16_t)0x0001) /*!< Source of update is counter overflow/underflow. */
+#define IS_TIM_UPDATE_SOURCE(SOURCE) (((SOURCE) == TIM_UpdateSource_Global) || \
+ ((SOURCE) == TIM_UpdateSource_Regular))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Output_Compare_Preload_State
+ * @{
+ */
+
+#define TIM_OCPreload_Enable ((uint16_t)0x0008)
+#define TIM_OCPreload_Disable ((uint16_t)0x0000)
+#define IS_TIM_OCPRELOAD_STATE(STATE) (((STATE) == TIM_OCPreload_Enable) || \
+ ((STATE) == TIM_OCPreload_Disable))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Output_Compare_Fast_State
+ * @{
+ */
+
+#define TIM_OCFast_Enable ((uint16_t)0x0004)
+#define TIM_OCFast_Disable ((uint16_t)0x0000)
+#define IS_TIM_OCFAST_STATE(STATE) (((STATE) == TIM_OCFast_Enable) || \
+ ((STATE) == TIM_OCFast_Disable))
+
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Output_Compare_Clear_State
+ * @{
+ */
+
+#define TIM_OCClear_Enable ((uint16_t)0x0080)
+#define TIM_OCClear_Disable ((uint16_t)0x0000)
+#define IS_TIM_OCCLEAR_STATE(STATE) (((STATE) == TIM_OCClear_Enable) || \
+ ((STATE) == TIM_OCClear_Disable))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Trigger_Output_Source
+ * @{
+ */
+
+#define TIM_TRGOSource_Reset ((uint16_t)0x0000)
+#define TIM_TRGOSource_Enable ((uint16_t)0x0010)
+#define TIM_TRGOSource_Update ((uint16_t)0x0020)
+#define TIM_TRGOSource_OC1 ((uint16_t)0x0030)
+#define TIM_TRGOSource_OC1Ref ((uint16_t)0x0040)
+#define TIM_TRGOSource_OC2Ref ((uint16_t)0x0050)
+#define TIM_TRGOSource_OC3Ref ((uint16_t)0x0060)
+#define TIM_TRGOSource_OC4Ref ((uint16_t)0x0070)
+#define IS_TIM_TRGO_SOURCE(SOURCE) (((SOURCE) == TIM_TRGOSource_Reset) || \
+ ((SOURCE) == TIM_TRGOSource_Enable) || \
+ ((SOURCE) == TIM_TRGOSource_Update) || \
+ ((SOURCE) == TIM_TRGOSource_OC1) || \
+ ((SOURCE) == TIM_TRGOSource_OC1Ref) || \
+ ((SOURCE) == TIM_TRGOSource_OC2Ref) || \
+ ((SOURCE) == TIM_TRGOSource_OC3Ref) || \
+ ((SOURCE) == TIM_TRGOSource_OC4Ref))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Slave_Mode
+ * @{
+ */
+
+#define TIM_SlaveMode_Reset ((uint16_t)0x0004)
+#define TIM_SlaveMode_Gated ((uint16_t)0x0005)
+#define TIM_SlaveMode_Trigger ((uint16_t)0x0006)
+#define TIM_SlaveMode_External1 ((uint16_t)0x0007)
+#define IS_TIM_SLAVE_MODE(MODE) (((MODE) == TIM_SlaveMode_Reset) || \
+ ((MODE) == TIM_SlaveMode_Gated) || \
+ ((MODE) == TIM_SlaveMode_Trigger) || \
+ ((MODE) == TIM_SlaveMode_External1))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Master_Slave_Mode
+ * @{
+ */
+
+#define TIM_MasterSlaveMode_Enable ((uint16_t)0x0080)
+#define TIM_MasterSlaveMode_Disable ((uint16_t)0x0000)
+#define IS_TIM_MSM_STATE(STATE) (((STATE) == TIM_MasterSlaveMode_Enable) || \
+ ((STATE) == TIM_MasterSlaveMode_Disable))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Flags
+ * @{
+ */
+
+#define TIM_FLAG_Update ((uint16_t)0x0001)
+#define TIM_FLAG_CC1 ((uint16_t)0x0002)
+#define TIM_FLAG_CC2 ((uint16_t)0x0004)
+#define TIM_FLAG_CC3 ((uint16_t)0x0008)
+#define TIM_FLAG_CC4 ((uint16_t)0x0010)
+#define TIM_FLAG_COM ((uint16_t)0x0020)
+#define TIM_FLAG_Trigger ((uint16_t)0x0040)
+#define TIM_FLAG_Break ((uint16_t)0x0080)
+#define TIM_FLAG_CC1OF ((uint16_t)0x0200)
+#define TIM_FLAG_CC2OF ((uint16_t)0x0400)
+#define TIM_FLAG_CC3OF ((uint16_t)0x0800)
+#define TIM_FLAG_CC4OF ((uint16_t)0x1000)
+#define IS_TIM_GET_FLAG(FLAG) (((FLAG) == TIM_FLAG_Update) || \
+ ((FLAG) == TIM_FLAG_CC1) || \
+ ((FLAG) == TIM_FLAG_CC2) || \
+ ((FLAG) == TIM_FLAG_CC3) || \
+ ((FLAG) == TIM_FLAG_CC4) || \
+ ((FLAG) == TIM_FLAG_COM) || \
+ ((FLAG) == TIM_FLAG_Trigger) || \
+ ((FLAG) == TIM_FLAG_Break) || \
+ ((FLAG) == TIM_FLAG_CC1OF) || \
+ ((FLAG) == TIM_FLAG_CC2OF) || \
+ ((FLAG) == TIM_FLAG_CC3OF) || \
+ ((FLAG) == TIM_FLAG_CC4OF))
+
+
+#define IS_TIM_CLEAR_FLAG(TIM_FLAG) ((((TIM_FLAG) & (uint16_t)0xE100) == 0x0000) && ((TIM_FLAG) != 0x0000))
+/**
+ * @}
+ */
+
+
+/** @defgroup TIM_Input_Capture_Filer_Value
+ * @{
+ */
+
+#define IS_TIM_IC_FILTER(ICFILTER) ((ICFILTER) <= 0xF)
+/**
+ * @}
+ */
+
+/** @defgroup TIM_External_Trigger_Filter
+ * @{
+ */
+
+#define IS_TIM_EXT_FILTER(EXTFILTER) ((EXTFILTER) <= 0xF)
+/**
+ * @}
+ */
+
+/** @defgroup TIM_OCReferenceClear
+ * @{
+ */
+#define TIM_OCReferenceClear_ETRF ((uint16_t)0x0008)
+#define TIM_OCReferenceClear_OCREFCLR ((uint16_t)0x0000)
+#define TIM_OCREFERENCECECLEAR_SOURCE(SOURCE) (((SOURCE) == TIM_OCReferenceClear_ETRF) || \
+ ((SOURCE) == TIM_OCReferenceClear_OCREFCLR))
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+
+/* TimeBase management ********************************************************/
+void TIM_DeInit(TIM_TypeDef* TIMx);
+void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
+void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
+void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode);
+void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode);
+void TIM_SetCounter(TIM_TypeDef* TIMx, uint32_t Counter);
+void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint32_t Autoreload);
+uint32_t TIM_GetCounter(TIM_TypeDef* TIMx);
+uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx);
+void TIM_UpdateDisableConfig(TIM_TypeDef* TIMx, FunctionalState NewState);
+void TIM_UpdateRequestConfig(TIM_TypeDef* TIMx, uint16_t TIM_UpdateSource);
+void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);
+void TIM_SelectOnePulseMode(TIM_TypeDef* TIMx, uint16_t TIM_OPMode);
+void TIM_SetClockDivision(TIM_TypeDef* TIMx, uint16_t TIM_CKD);
+void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);
+
+/* Advanced-control timers (TIM1) specific features*******************/
+void TIM_BDTRConfig(TIM_TypeDef* TIMx, TIM_BDTRInitTypeDef *TIM_BDTRInitStruct);
+void TIM_BDTRStructInit(TIM_BDTRInitTypeDef* TIM_BDTRInitStruct);
+void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState);
+
+/* Output Compare management **************************************************/
+void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
+void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
+void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
+void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
+void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct);
+void TIM_SelectOCxM(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode);
+void TIM_SetCompare1(TIM_TypeDef* TIMx, uint32_t Compare1);
+void TIM_SetCompare2(TIM_TypeDef* TIMx, uint32_t Compare2);
+void TIM_SetCompare3(TIM_TypeDef* TIMx, uint32_t Compare3);
+void TIM_SetCompare4(TIM_TypeDef* TIMx, uint32_t Compare4);
+void TIM_ForcedOC1Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
+void TIM_ForcedOC2Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
+void TIM_ForcedOC3Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
+void TIM_ForcedOC4Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
+void TIM_CCPreloadControl(TIM_TypeDef* TIMx, FunctionalState NewState);
+void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
+void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
+void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
+void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
+void TIM_OC1FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
+void TIM_OC2FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
+void TIM_OC3FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
+void TIM_OC4FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
+void TIM_ClearOC1Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
+void TIM_ClearOC2Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
+void TIM_ClearOC3Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
+void TIM_ClearOC4Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
+void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
+void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
+void TIM_OC2PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
+void TIM_OC2NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
+void TIM_OC3PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
+void TIM_OC3NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
+void TIM_OC4PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
+void TIM_SelectOCREFClear(TIM_TypeDef* TIMx, uint16_t TIM_OCReferenceClear);
+void TIM_CCxCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCx);
+void TIM_CCxNCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCxN);
+void TIM_SelectCOM(TIM_TypeDef* TIMx, FunctionalState NewState);
+
+/* Input Capture management ***************************************************/
+void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);
+void TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitStruct);
+void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);
+uint32_t TIM_GetCapture1(TIM_TypeDef* TIMx);
+uint32_t TIM_GetCapture2(TIM_TypeDef* TIMx);
+uint32_t TIM_GetCapture3(TIM_TypeDef* TIMx);
+uint32_t TIM_GetCapture4(TIM_TypeDef* TIMx);
+void TIM_SetIC1Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
+void TIM_SetIC2Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
+void TIM_SetIC3Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
+void TIM_SetIC4Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
+
+/* Interrupts and flags management ***************************************/
+void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);
+void TIM_GenerateEvent(TIM_TypeDef* TIMx, uint16_t TIM_EventSource);
+FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
+void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
+ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);
+void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);
+
+/* Clocks management **********************************************************/
+void TIM_InternalClockConfig(TIM_TypeDef* TIMx);
+void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);
+void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource,
+ uint16_t TIM_ICPolarity, uint16_t ICFilter);
+void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,
+ uint16_t ExtTRGFilter);
+void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler,
+ uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);
+
+
+/* Synchronization management *************************************************/
+void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);
+void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource);
+void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode);
+void TIM_SelectMasterSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_MasterSlaveMode);
+void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,
+ uint16_t ExtTRGFilter);
+
+/* Specific interface management **********************************************/
+void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode,
+ uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity);
+void TIM_SelectHallSensor(TIM_TypeDef* TIMx, FunctionalState NewState);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__HK32F030M_TIM_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_usart.h b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_usart.h
new file mode 100644
index 0000000..bd71c5d
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_usart.h
@@ -0,0 +1,541 @@
+/**
+ ******************************************************************************
+ * @file hk32f030m_usart.h
+ * @version V1.0.1
+ * author Rakan.Z/wing.Wang
+ * @date 2019-12-17
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __HK32F030M_USART_H
+#define __HK32F030M_USART_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "hk32f030m.h"
+
+/** @addtogroup USART
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+
+
+
+/**
+ * @brief USART Init Structure definition
+ */
+
+typedef struct
+{
+ uint32_t USART_BaudRate; /*!< This member configures the USART communication baud rate.
+ The baud rate is computed using the following formula:
+ - IntegerDivider = ((PCLKx) / (16 * (USART_InitStruct->USART_BaudRate)))
+ - FractionalDivider = ((IntegerDivider - ((uint32_t) IntegerDivider)) * 16) + 0.5 */
+
+ uint32_t USART_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 USART_StopBits; /*!< Specifies the number of stop bits transmitted.
+ This parameter can be a value of @ref USART_Stop_Bits */
+
+ uint32_t USART_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 USART_Mode; /*!< Specifies wether the Receive or Transmit mode is enabled or disabled.
+ This parameter can be a value of @ref USART_Mode */
+
+ uint32_t USART_HardwareFlowControl; /*!< Specifies wether the hardware flow control mode is enabled
+ or disabled.
+ This parameter can be a value of @ref USART_Hardware_Flow_Control*/
+} USART_InitTypeDef;
+
+/**
+ * @brief USART Clock Init Structure definition
+ */
+
+typedef struct
+{
+ uint32_t USART_Clock; /*!< Specifies whether the USART clock is enabled or disabled.
+ This parameter can be a value of @ref USART_Clock */
+
+ uint32_t USART_CPOL; /*!< Specifies the steady state of the serial clock.
+ This parameter can be a value of @ref USART_Clock_Polarity */
+
+ uint32_t USART_CPHA; /*!< Specifies the clock transition on which the bit capture is made.
+ This parameter can be a value of @ref USART_Clock_Phase */
+
+ uint32_t USART_LastBit; /*!< 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_ClockInitTypeDef;
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup USART_Exported_Constants
+ * @{
+ */
+
+#define IS_USART_ALL_PERIPH(PERIPH) ((PERIPH) == USART1)
+
+#define IS_USART_1_PERIPH(PERIPH) ((PERIPH) == USART1)
+
+/** @defgroup USART_Word_Length
+ * @{
+ */
+
+#define USART_WordLength_8b ((uint32_t)0x00000000)
+#define USART_WordLength_9b USART_CR1_M /* should be ((uint32_t)0x00001000) */
+#define USART_WordLength_7b ((uint32_t)0x10001000)
+#define IS_USART_WORD_LENGTH(LENGTH) (((LENGTH) == USART_WordLength_8b) || \
+ ((LENGTH) == USART_WordLength_9b) || \
+ ((LENGTH) == USART_WordLength_7b))
+/**
+ * @}
+ */
+
+/** @defgroup USART_Stop_Bits
+ * @{
+ */
+
+#define USART_StopBits_1 ((uint32_t)0x00000000)
+#define USART_StopBits_2 USART_CR2_STOP_1
+#define USART_StopBits_1_5 (USART_CR2_STOP_0 | USART_CR2_STOP_1)
+#define IS_USART_STOPBITS(STOPBITS) (((STOPBITS) == USART_StopBits_1) || \
+ ((STOPBITS) == USART_StopBits_2) || \
+ ((STOPBITS) == USART_StopBits_1_5))
+/**
+ * @}
+ */
+
+/** @defgroup USART_Parity
+ * @{
+ */
+
+#define USART_Parity_No ((uint32_t)0x00000000)
+#define USART_Parity_Even USART_CR1_PCE
+#define USART_Parity_Odd (USART_CR1_PCE | USART_CR1_PS)
+#define IS_USART_PARITY(PARITY) (((PARITY) == USART_Parity_No) || \
+ ((PARITY) == USART_Parity_Even) || \
+ ((PARITY) == USART_Parity_Odd))
+/**
+ * @}
+ */
+
+/** @defgroup USART_Mode
+ * @{
+ */
+
+#define USART_Mode_Rx USART_CR1_RE
+#define USART_Mode_Tx USART_CR1_TE
+#define IS_USART_MODE(MODE) ((((MODE) & (uint32_t)0xFFFFFFF3) == 0x00) && \
+ ((MODE) != (uint32_t)0x00))
+/**
+ * @}
+ */
+
+/** @defgroup USART_Hardware_Flow_Control
+ * @{
+ */
+
+#define USART_HardwareFlowControl_None ((uint32_t)0x00000000)
+#define USART_HardwareFlowControl_RTS USART_CR3_RTSE
+#define USART_HardwareFlowControl_CTS USART_CR3_CTSE
+#define USART_HardwareFlowControl_RTS_CTS (USART_CR3_RTSE | USART_CR3_CTSE)
+#define IS_USART_HARDWARE_FLOW_CONTROL(CONTROL)\
+ (((CONTROL) == USART_HardwareFlowControl_None) || \
+ ((CONTROL) == USART_HardwareFlowControl_RTS) || \
+ ((CONTROL) == USART_HardwareFlowControl_CTS) || \
+ ((CONTROL) == USART_HardwareFlowControl_RTS_CTS))
+/**
+ * @}
+ */
+
+/** @defgroup USART_Clock
+ * @{
+ */
+
+#define USART_Clock_Disable ((uint32_t)0x00000000)
+#define USART_Clock_Enable USART_CR2_CLKEN
+#define IS_USART_CLOCK(CLOCK) (((CLOCK) == USART_Clock_Disable) || \
+ ((CLOCK) == USART_Clock_Enable))
+/**
+ * @}
+ */
+
+/** @defgroup USART_Clock_Polarity
+ * @{
+ */
+
+#define USART_CPOL_Low ((uint32_t)0x00000000)
+#define USART_CPOL_High USART_CR2_CPOL
+#define IS_USART_CPOL(CPOL) (((CPOL) == USART_CPOL_Low) || ((CPOL) == USART_CPOL_High))
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_Clock_Phase
+ * @{
+ */
+
+#define USART_CPHA_1Edge ((uint32_t)0x00000000)
+#define USART_CPHA_2Edge USART_CR2_CPHA
+#define IS_USART_CPHA(CPHA) (((CPHA) == USART_CPHA_1Edge) || ((CPHA) == USART_CPHA_2Edge))
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_Last_Bit
+ * @{
+ */
+
+#define USART_LastBit_Disable ((uint32_t)0x00000000)
+#define USART_LastBit_Enable USART_CR2_LBCL
+#define IS_USART_LASTBIT(LASTBIT) (((LASTBIT) == USART_LastBit_Disable) || \
+ ((LASTBIT) == USART_LastBit_Enable))
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_MuteMode_WakeUp_methods
+ * @{
+ */
+
+#define USART_WakeUp_IdleLine ((uint32_t)0x00000000)
+#define USART_WakeUp_AddressMark USART_CR1_WAKE
+#define IS_USART_MUTEMODE_WAKEUP(WAKEUP) (((WAKEUP) == USART_WakeUp_IdleLine) || \
+ ((WAKEUP) == USART_WakeUp_AddressMark))
+/**
+ * @}
+ */
+
+/** @defgroup USART_Address_Detection
+ * @{
+ */
+
+#define USART_AddressLength_4b ((uint32_t)0x00000000)
+#define USART_AddressLength_7b USART_CR2_ADDM7
+#define IS_USART_ADDRESS_DETECTION(ADDRESS) (((ADDRESS) == USART_AddressLength_4b) || \
+ ((ADDRESS) == USART_AddressLength_7b))
+/**
+ * @}
+ */
+
+/** @defgroup USART_StopMode_WakeUp_methods
+ * @{
+ */
+
+#define USART_WakeUpSource_AddressMatch ((uint32_t)0x00000000)
+#define USART_WakeUpSource_StartBit USART_CR3_WUS_1
+#define USART_WakeUpSource_RXNE (USART_CR3_WUS_0 | USART_CR3_WUS_1)
+#define IS_USART_STOPMODE_WAKEUPSOURCE(SOURCE) (((SOURCE) == USART_WakeUpSource_AddressMatch) || \
+ ((SOURCE) == USART_WakeUpSource_StartBit) || \
+ ((SOURCE) == USART_WakeUpSource_RXNE))
+/**
+ * @}
+ */
+
+/** @defgroup USART_LIN_Break_Detection_Length
+ * @{
+ */
+
+#define USART_LINBreakDetectLength_10b ((uint32_t)0x00000000)
+#define USART_LINBreakDetectLength_11b USART_CR2_LBDL
+#define IS_USART_LIN_BREAK_DETECT_LENGTH(LENGTH) \
+ (((LENGTH) == USART_LINBreakDetectLength_10b) || \
+ ((LENGTH) == USART_LINBreakDetectLength_11b))
+/**
+ * @}
+ */
+
+/** @defgroup USART_IrDA_Low_Power
+ * @{
+ */
+
+#define USART_IrDAMode_LowPower USART_CR3_IRLP
+#define USART_IrDAMode_Normal ((uint32_t)0x00000000)
+#define IS_USART_IRDA_MODE(MODE) (((MODE) == USART_IrDAMode_LowPower) || \
+ ((MODE) == USART_IrDAMode_Normal))
+/**
+ * @}
+ */
+
+/** @defgroup USART_DE_Polarity
+ * @{
+ */
+
+#define USART_DEPolarity_High ((uint32_t)0x00000000)
+#define USART_DEPolarity_Low USART_CR3_DEP
+#define IS_USART_DE_POLARITY(POLARITY) (((POLARITY) == USART_DEPolarity_Low) || \
+ ((POLARITY) == USART_DEPolarity_High))
+/**
+ * @}
+ */
+
+/** @defgroup USART_Inversion_Pins
+ * @{
+ */
+
+#define USART_InvPin_Tx USART_CR2_TXINV
+#define USART_InvPin_Rx USART_CR2_RXINV
+#define IS_USART_INVERSTION_PIN(PIN) ((((PIN) & (uint32_t)0xFFFCFFFF) == 0x00) && \
+ ((PIN) != (uint32_t)0x00))
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_AutoBaudRate_Mode
+ * @{
+ */
+
+#define USART_AutoBaudRate_StartBit ((uint32_t)0x00000000)
+#define USART_AutoBaudRate_FallingEdge USART_CR2_ABRMODE_0
+#define IS_USART_AUTOBAUDRATE_MODE(MODE) (((MODE) == USART_AutoBaudRate_StartBit) || \
+ ((MODE) == USART_AutoBaudRate_FallingEdge))
+/**
+ * @}
+ */
+
+/** @defgroup USART_OVR_DETECTION
+ * @{
+ */
+
+#define USART_OVRDetection_Enable ((uint32_t)0x00000000)
+#define USART_OVRDetection_Disable USART_CR3_OVRDIS
+#define IS_USART_OVRDETECTION(OVR) (((OVR) == USART_OVRDetection_Enable)|| \
+ ((OVR) == USART_OVRDetection_Disable))
+/**
+ * @}
+ */
+/** @defgroup USART_Request
+ * @{
+ */
+
+#define USART_Request_ABRRQ USART_RQR_ABRRQ
+#define USART_Request_SBKRQ USART_RQR_SBKRQ
+#define USART_Request_MMRQ USART_RQR_MMRQ
+#define USART_Request_RXFRQ USART_RQR_RXFRQ
+#define USART_Request_TXFRQ USART_RQR_TXFRQ
+
+#define IS_USART_REQUEST(REQUEST) (((REQUEST) == USART_Request_TXFRQ) || \
+ ((REQUEST) == USART_Request_RXFRQ) || \
+ ((REQUEST) == USART_Request_MMRQ) || \
+ ((REQUEST) == USART_Request_SBKRQ) || \
+ ((REQUEST) == USART_Request_ABRRQ))
+/**
+ * @}
+ */
+
+/** @defgroup USART_Flags
+ * @{
+ */
+#define USART_FLAG_REACK USART_ISR_REACK
+#define USART_FLAG_TEACK USART_ISR_TEACK
+#define USART_FLAG_WU USART_ISR_WUF
+#define USART_FLAG_RWU USART_ISR_RWU
+#define USART_FLAG_SBK USART_ISR_SBKF
+#define USART_FLAG_CM USART_ISR_CMF
+#define USART_FLAG_BUSY USART_ISR_BUSY
+#define USART_FLAG_ABRF USART_ISR_ABRF
+#define USART_FLAG_ABRE USART_ISR_ABRE
+#define USART_FLAG_EOB USART_ISR_EOBF
+#define USART_FLAG_RTO USART_ISR_RTOF
+#define USART_FLAG_nCTSS USART_ISR_CTS
+#define USART_FLAG_CTS USART_ISR_CTSIF
+#define USART_FLAG_LBDF USART_ISR_LBDF
+#define USART_FLAG_TXE USART_ISR_TXE
+#define USART_FLAG_TC USART_ISR_TC
+#define USART_FLAG_RXNE USART_ISR_RXNE
+#define USART_FLAG_IDLE USART_ISR_IDLE
+#define USART_FLAG_ORE USART_ISR_ORE
+#define USART_FLAG_NE USART_ISR_NE
+#define USART_FLAG_FE USART_ISR_FE
+#define USART_FLAG_PE USART_ISR_PE
+#define IS_USART_FLAG(FLAG) (((FLAG) == USART_FLAG_PE) || ((FLAG) == USART_FLAG_TXE) || \
+ ((FLAG) == USART_FLAG_TC) || ((FLAG) == USART_FLAG_RXNE) || \
+ ((FLAG) == USART_FLAG_IDLE) || ((FLAG) == USART_ISR_LBDF) || \
+ ((FLAG) == USART_FLAG_CTS) || ((FLAG) == USART_FLAG_ORE) || \
+ ((FLAG) == USART_FLAG_NE) || ((FLAG) == USART_FLAG_FE) || \
+ ((FLAG) == USART_FLAG_nCTSS) || ((FLAG) == USART_FLAG_RTO) || \
+ ((FLAG) == USART_FLAG_EOB) || ((FLAG) == USART_FLAG_ABRE) || \
+ ((FLAG) == USART_FLAG_ABRF) || ((FLAG) == USART_FLAG_BUSY) || \
+ ((FLAG) == USART_FLAG_CM) || ((FLAG) == USART_FLAG_SBK) || \
+ ((FLAG) == USART_FLAG_RWU) || ((FLAG) == USART_FLAG_WU) || \
+ ((FLAG) == USART_FLAG_TEACK)|| ((FLAG) == USART_FLAG_REACK))
+
+#define IS_USART_CLEAR_FLAG(FLAG) (((FLAG) == USART_FLAG_WU) || ((FLAG) == USART_FLAG_TC) || \
+ ((FLAG) == USART_FLAG_IDLE) || ((FLAG) == USART_FLAG_ORE) || \
+ ((FLAG) == USART_FLAG_NE) || ((FLAG) == USART_FLAG_FE) || \
+ ((FLAG) == USART_FLAG_LBDF) || ((FLAG) == USART_FLAG_CTS) || \
+ ((FLAG) == USART_FLAG_RTO) || ((FLAG) == USART_FLAG_EOB) || \
+ ((FLAG) == USART_FLAG_CM) || ((FLAG) == USART_FLAG_PE))
+/**
+ * @}
+ */
+
+/** @defgroup USART_Interrupt_definition
+ * @brief USART Interrupt definition
+ * USART_IT possible values
+ * Elements values convention: 0xZZZZYYXX
+ * XX: Position of the corresponding Interrupt
+ * YY: Register index
+ * ZZZZ: Flag position
+ * @{
+ */
+
+#define USART_IT_WU ((uint32_t)0x00140316)
+#define USART_IT_CM ((uint32_t)0x0011010E)
+#define USART_IT_EOB ((uint32_t)0x000C011B)
+#define USART_IT_RTO ((uint32_t)0x000B011A)
+#define USART_IT_PE ((uint32_t)0x00000108)
+#define USART_IT_TXE ((uint32_t)0x00070107)
+#define USART_IT_TC ((uint32_t)0x00060106)
+#define USART_IT_RXNE ((uint32_t)0x00050105)
+#define USART_IT_IDLE ((uint32_t)0x00040104)
+#define USART_IT_LBD ((uint32_t)0x00080206)
+#define USART_IT_CTS ((uint32_t)0x0009030A)
+#define USART_IT_ERR ((uint32_t)0x00000300)
+#define USART_IT_ORE ((uint32_t)0x00030300)
+#define USART_IT_NE ((uint32_t)0x00020300)
+#define USART_IT_FE ((uint32_t)0x00010300)
+
+#define IS_USART_CONFIG_IT(IT) (((IT) == USART_IT_PE) || ((IT) == USART_IT_TXE) || \
+ ((IT) == USART_IT_TC) || ((IT) == USART_IT_RXNE) || \
+ ((IT) == USART_IT_IDLE) || ((IT) == USART_IT_LBD) || \
+ ((IT) == USART_IT_CTS) || ((IT) == USART_IT_ERR) || \
+ ((IT) == USART_IT_RTO) || ((IT) == USART_IT_EOB) || \
+ ((IT) == USART_IT_CM) || ((IT) == USART_IT_WU))
+
+#define IS_USART_GET_IT(IT) (((IT) == USART_IT_PE) || ((IT) == USART_IT_TXE) || \
+ ((IT) == USART_IT_TC) || ((IT) == USART_IT_RXNE) || \
+ ((IT) == USART_IT_IDLE) || ((IT) == USART_IT_LBD) || \
+ ((IT) == USART_IT_CTS) || ((IT) == USART_IT_ORE) || \
+ ((IT) == USART_IT_NE) || ((IT) == USART_IT_FE) || \
+ ((IT) == USART_IT_RTO) || ((IT) == USART_IT_EOB) || \
+ ((IT) == USART_IT_CM) || ((IT) == USART_IT_WU))
+
+#define IS_USART_CLEAR_IT(IT) (((IT) == USART_IT_TC) || ((IT) == USART_IT_PE) || \
+ ((IT) == USART_IT_FE) || ((IT) == USART_IT_NE) || \
+ ((IT) == USART_IT_ORE) || ((IT) == USART_IT_IDLE) || \
+ ((IT) == USART_IT_LBD) || ((IT) == USART_IT_CTS) || \
+ ((IT) == USART_IT_RTO) || ((IT) == USART_IT_EOB) || \
+ ((IT) == USART_IT_CM) || ((IT) == USART_IT_WU))
+/**
+ * @}
+ */
+
+/** @defgroup USART_Global_definition
+ * @{
+ */
+
+#define IS_USART_BAUDRATE(BAUDRATE) (((BAUDRATE) > 0) && ((BAUDRATE) < 0x005B8D81))
+#define IS_USART_DE_ASSERTION_DEASSERTION_TIME(TIME) ((TIME) <= 0x1F)
+#define IS_USART_AUTO_RETRY_COUNTER(COUNTER) ((COUNTER) <= 0x7)
+#define IS_USART_TIMEOUT(TIMEOUT) ((TIMEOUT) <= 0x00FFFFFF)
+#define IS_USART_DATA(DATA) ((DATA) <= 0x1FF)
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+
+/* Initialization and Configuration functions *********************************/
+void USART_DeInit(USART_TypeDef* USARTx);
+void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);
+void USART_StructInit(USART_InitTypeDef* USART_InitStruct);
+void USART_ClockInit(USART_TypeDef* USARTx, USART_ClockInitTypeDef* USART_ClockInitStruct);
+void USART_ClockStructInit(USART_ClockInitTypeDef* USART_ClockInitStruct);
+void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState);
+void USART_DirectionModeCmd(USART_TypeDef* USARTx, uint32_t USART_DirectionMode, FunctionalState NewState);
+void USART_SetPrescaler(USART_TypeDef* USARTx, uint8_t USART_Prescaler);
+void USART_OverSampling8Cmd(USART_TypeDef* USARTx, FunctionalState NewState);
+void USART_OneBitMethodCmd(USART_TypeDef* USARTx, FunctionalState NewState);
+void USART_MSBFirstCmd(USART_TypeDef* USARTx, FunctionalState NewState);
+void USART_DataInvCmd(USART_TypeDef* USARTx, FunctionalState NewState);
+void USART_InvPinCmd(USART_TypeDef* USARTx, uint32_t USART_InvPin, FunctionalState NewState);
+void USART_SWAPPinCmd(USART_TypeDef* USARTx, FunctionalState NewState);
+void USART_ReceiverTimeOutCmd(USART_TypeDef* USARTx, FunctionalState NewState);
+void USART_SetReceiverTimeOut(USART_TypeDef* USARTx, uint32_t USART_ReceiverTimeOut);
+
+/* STOP Mode functions ********************************************************/
+void USART_STOPModeCmd(USART_TypeDef* USARTx, FunctionalState NewState);
+void USART_StopModeWakeUpSourceConfig(USART_TypeDef* USARTx, uint32_t USART_WakeUpSource);
+
+/* AutoBaudRate functions *****************************************************/
+void USART_AutoBaudRateCmd(USART_TypeDef* USARTx, FunctionalState NewState);
+void USART_AutoBaudRateConfig(USART_TypeDef* USARTx, uint32_t USART_AutoBaudRate);
+
+/* Data transfers functions ***************************************************/
+void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);
+uint16_t USART_ReceiveData(USART_TypeDef* USARTx);
+
+/* Multi-Processor Communication functions ************************************/
+void USART_SetAddress(USART_TypeDef* USARTx, uint8_t USART_Address);
+void USART_MuteModeWakeUpConfig(USART_TypeDef* USARTx, uint32_t USART_WakeUp);
+void USART_MuteModeCmd(USART_TypeDef* USARTx, FunctionalState NewState);
+void USART_AddressDetectionConfig(USART_TypeDef* USARTx, uint32_t USART_AddressLength);
+
+/* LIN mode functions *********************************************************/
+void USART_LINBreakDetectLengthConfig(USART_TypeDef* USARTx, uint32_t USART_LINBreakDetectLength);
+void USART_LINCmd(USART_TypeDef* USARTx, FunctionalState NewState);
+
+/* Half-duplex mode function **************************************************/
+void USART_HalfDuplexCmd(USART_TypeDef* USARTx, FunctionalState NewState);
+
+/* Smartcard mode functions ***************************************************/
+void USART_SmartCardCmd(USART_TypeDef* USARTx, FunctionalState NewState);
+void USART_SmartCardNACKCmd(USART_TypeDef* USARTx, FunctionalState NewState);
+void USART_SetGuardTime(USART_TypeDef* USARTx, uint8_t USART_GuardTime);
+void USART_SetAutoRetryCount(USART_TypeDef* USARTx, uint8_t USART_AutoCount);
+void USART_SetBlockLength(USART_TypeDef* USARTx, uint8_t USART_BlockLength);
+
+/* IrDA mode functions ********************************************************/
+void USART_IrDAConfig(USART_TypeDef* USARTx, uint32_t USART_IrDAMode);
+void USART_IrDACmd(USART_TypeDef* USARTx, FunctionalState NewState);
+
+/* RS485 mode functions *******************************************************/
+void USART_DECmd(USART_TypeDef* USARTx, FunctionalState NewState);
+void USART_DEPolarityConfig(USART_TypeDef* USARTx, uint32_t USART_DEPolarity);
+void USART_SetDEAssertionTime(USART_TypeDef* USARTx, uint32_t USART_DEAssertionTime);
+void USART_SetDEDeassertionTime(USART_TypeDef* USARTx, uint32_t USART_DEDeassertionTime);
+/* Interrupts and flags management functions **********************************/
+void USART_ITConfig(USART_TypeDef* USARTx, uint32_t USART_IT, FunctionalState NewState);
+void USART_RequestCmd(USART_TypeDef* USARTx, uint32_t USART_Request, FunctionalState NewState);
+void USART_OverrunDetectionConfig(USART_TypeDef* USARTx, uint32_t USART_OVRDetection);
+FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint32_t USART_FLAG);
+void USART_ClearFlag(USART_TypeDef* USARTx, uint32_t USART_FLAG);
+ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint32_t USART_IT);
+void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint32_t USART_IT);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __HK32F030M_USART_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_wwdg.h b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_wwdg.h
new file mode 100644
index 0000000..9ec1b92
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/inc/hk32f030m_wwdg.h
@@ -0,0 +1,86 @@
+/**
+ ******************************************************************************
+ * @file hk32f030m_wwdg.h
+ * @version V1.0.1
+ * author Rakan.Z/wing.Wang
+ * @date 2019-12-15
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __HK32F030M_WWDG_H
+#define __HK32F030M_WWDG_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "hk32f030m.h"
+
+
+/** @addtogroup WWDG
+ * @{
+ */
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup WWDG_Exported_Constants
+ * @{
+ */
+
+/** @defgroup WWDG_Prescaler
+ * @{
+ */
+
+#define WWDG_Prescaler_1 ((uint32_t)0x00000000)
+#define WWDG_Prescaler_2 ((uint32_t)0x00000080)
+#define WWDG_Prescaler_4 ((uint32_t)0x00000100)
+#define WWDG_Prescaler_8 ((uint32_t)0x00000180)
+#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_VALUE(VALUE) ((VALUE) <= 0x7F)
+#define IS_WWDG_COUNTER(COUNTER) (((COUNTER) >= 0x40) && ((COUNTER) <= 0x7F))
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+/* Function used to set the WWDG configuration to the default reset state ****/
+void WWDG_DeInit(void);
+
+/* Prescaler, Refresh window and Counter configuration functions **************/
+void WWDG_SetPrescaler(uint32_t WWDG_Prescaler);
+void WWDG_SetWindowValue(uint8_t WindowValue);
+void WWDG_EnableIT(void);
+void WWDG_SetCounter(uint8_t Counter);
+
+/* WWDG activation functions **************************************************/
+void WWDG_Enable(uint8_t Counter);
+
+/* Interrupts and flags management functions **********************************/
+FlagStatus WWDG_GetFlagStatus(void);
+void WWDG_ClearFlag(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __HK32F030M_WWDG_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_adc.c b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_adc.c
new file mode 100644
index 0000000..029f6cd
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_adc.c
@@ -0,0 +1,1084 @@
+/**
+ ******************************************************************************
+ * @file hk32f030m_adc.c
+ * @version V1.0.0
+ * @date 2019-12-30
+ * @author Rakan.Z/Jane.li
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "hk32f030m_adc.h"
+#include "hk32f030m_rcc.h"
+
+
+/** @defgroup ADC
+ * @brief ADC driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* ADC CFGR mask */
+#define CFGR1_CLEAR_MASK ((uint32_t)0xFFFFD200)//jane changed
+
+/* Calibration time out */
+#define CALIBRATION_TIMEOUT ((uint32_t)0x0000F000)
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup ADC_Private_Functions
+ * @{
+ */
+
+/** @defgroup ADC_Group1 Initialization and Configuration functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Initialization and Configuration functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to:
+ (+) Initialize and configure the ADC Prescaler
+ (+) ADC Conversion Resolution (12bit..6bit)
+ (+) ADC Continuous Conversion Mode (Continuous or Single conversion)
+ (+) External trigger Edge and source
+ (+) Converted data alignment (left or right)
+ (+) The direction in which the channels will be scanned in the sequence
+ (+) Enable or disable the ADC peripheral
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Deinitializes ADC1 peripheral registers to their default reset values.
+ * @param ADCx: where x can be 1 to select the ADC peripheral.
+ * @retval None
+ */
+void ADC_DeInit(ADC_TypeDef* ADCx)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+
+ if(ADCx == ADC1)
+ {
+ /* Enable ADC1 reset state */
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC, ENABLE);
+
+ /* Release ADC1 from reset state */
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC, DISABLE);
+ }
+}
+
+// todo
+// fixme
+// tag
+// done
+// note
+
+/**
+ * @brief Initializes the ADCx peripheral according to the specified parameters
+ * in the ADC_InitStruct.
+ * @note This function is used to configure the global features of the ADC (
+ * Resolution, Data Alignment, continuous mode activation, External
+ * trigger source and edge, Sequence Scan Direction).
+ * @param ADCx: where x can be 1 to select the ADC peripheral.
+ * @param ADC_InitStruct: pointer to an ADC_InitTypeDef structure that contains
+ * the configuration information for the specified ADC peripheral.
+ * @retval None
+ */
+void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_FUNCTIONAL_STATE(ADC_InitStruct->ADC_ContinuousConvMode));
+ assert_param(IS_ADC_EXT_TRIG_EDGE(ADC_InitStruct->ADC_ExternalTrigConvEdge));
+ assert_param(IS_ADC_EXTERNAL_TRIG_CONV(ADC_InitStruct->ADC_ExternalTrigConv));
+ assert_param(IS_ADC_DATA_ALIGN(ADC_InitStruct->ADC_DataAlign));
+ assert_param(IS_ADC_SCAN_DIRECTION(ADC_InitStruct->ADC_ScanDirection));
+
+ /* Get the ADCx CFGR value */
+ tmpreg = ADCx->CFGR1;
+
+ /* Clear SCANDIR, ALIGN, EXTSEL[2:0], EXTEN[1:0] and CONT bits */
+ tmpreg &= CFGR1_CLEAR_MASK;
+
+ /*---------------------------- ADCx CFGR Configuration ---------------------*/
+
+ /* Set CONT bit according to ADC_ContinuousConvMode value */
+ /* Set EXTEN[1:0] bits according to ADC_ExternalTrigConvEdge value */
+ /* Set EXTSEL[2:0] bits according to ADC_ExternalTrigConv value */
+ /* Set ALIGN bit according to ADC_DataAlign value */
+ /* Set SCANDIR bit according to ADC_ScanDirection value */
+
+ tmpreg |= (uint32_t)(((uint32_t)(ADC_InitStruct->ADC_ContinuousConvMode) << 13) |
+ ADC_InitStruct->ADC_ExternalTrigConvEdge | ADC_InitStruct->ADC_ExternalTrigConv |
+ ADC_InitStruct->ADC_DataAlign | ADC_InitStruct->ADC_ScanDirection);
+
+ /* Write to ADCx CFGR */
+ ADCx->CFGR1 = tmpreg;
+}
+
+/**
+ * @brief Fills each ADC_InitStruct member with its default value.
+ * @note This function is used to initialize the global features of the ADC (
+ * Data Alignment, continuous mode activation, External
+ * trigger source and edge, Sequence Scan Direction).
+ * @param ADC_InitStruct: pointer to an ADC_InitTypeDef structure which will
+ * be initialized.
+ * @retval None
+ */
+void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct)
+{
+ /* Reset ADC init structure parameters values */
+
+ /* Initialize the ADC_ContinuousConvMode member */
+ ADC_InitStruct->ADC_ContinuousConvMode = DISABLE;
+
+ /* Initialize the ADC_ExternalTrigConvEdge member */
+ ADC_InitStruct->ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
+
+ /* Initialize the ADC_ExternalTrigConv member */
+ ADC_InitStruct->ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_TRGO;
+
+ /* Initialize the ADC_DataAlign member */
+ ADC_InitStruct->ADC_DataAlign = ADC_DataAlign_Right;
+
+ /* Initialize the ADC_ScanDirection member */
+ ADC_InitStruct->ADC_ScanDirection = ADC_ScanDirection_Upward;
+}
+
+/**
+ * @brief Enables or disables the specified ADC peripheral.
+ * @param ADCx: where x can be 1 to select the ADC1 peripheral.
+ * @param NewState: new state of the ADCx peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Set the ADEN bit to Enable the ADC peripheral */
+ ADCx->CR |= (uint32_t)ADC_CR_ADEN;
+ }
+ else
+ {
+ /* Set the ADDIS to Disable the ADC peripheral */
+ ADCx->CR |= (uint32_t)ADC_CR_ADDIS;
+ }
+}
+
+/**
+ * @brief Configure the ADC to either be clocked by the asynchronous clock(which is
+ * independent, the dedicated 14MHz clock) or the synchronous clock derived from
+ * the APB clock of the ADC bus interface divided by 2 or 4
+ * @note This function can be called only when ADC is disabled.
+ * @param ADCx: where x can be 1 to select the ADC1 peripheral.
+ * @param ADC_ClockMode: This parameter can be :
+ * @arg ADC_ClockMode_AsynClk: ADC clocked by the dedicated 14MHz clock
+ * @arg ADC_ClockMode_SynClkDiv2: ADC clocked by PCLK/2
+ * @arg ADC_ClockMode_SynClkDiv4: ADC clocked by PCLK/4
+ * @retval None
+ */
+void ADC_ClockModeConfig(ADC_TypeDef* ADCx, uint32_t ADC_ClockMode)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_CLOCKMODE(ADC_ClockMode));
+
+ /* Configure the ADC Clock mode according to ADC_ClockMode */
+ ADCx->CFGR2 = (uint32_t)ADC_ClockMode;
+
+}
+
+/**
+ * @brief Enables or disables the jitter when the ADC is clocked by PCLK div2
+ * or div4
+ * @note This function is obsolete and maintained for legacy purpose only. ADC_ClockModeConfig()
+ * function should be used instead.
+ * @param ADCx: where x can be 1 to select the ADC1 peripheral.
+ * @param ADC_JitterOff: This parameter can be :
+ * @arg ADC_JitterOff_PCLKDiv2: Remove jitter when ADC is clocked by PLCK divided by 2
+ * @arg ADC_JitterOff_PCLKDiv4: Remove jitter when ADC is clocked by PLCK divided by 4
+ * @param NewState: new state of the ADCx jitter.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void ADC_JitterCmd(ADC_TypeDef* ADCx, uint32_t ADC_JitterOff, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_JITTEROFF(ADC_JitterOff));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Disable Jitter */
+ ADCx->CFGR2 |= (uint32_t)ADC_JitterOff;
+ }
+ else
+ {
+ /* Enable Jitter */
+ ADCx->CFGR2 &= (uint32_t)(~ADC_JitterOff);
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup ADC_Group2 Power saving functions
+ * @brief Power saving functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Power saving functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to reduce power consumption.
+ [..] The two function must be combined to get the maximal benefits:
+ When the ADC frequency is higher than the CPU one, it is recommended to
+ (#) Enable the Auto Delayed Conversion mode :
+ ==> using ADC_WaitModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
+ (#) Enable the power off in Delay phases :
+ ==> using ADC_AutoPowerOffCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the ADC Power Off.
+ * @note ADC power-on and power-off can be managed by hardware to cut the
+ * consumption when the ADC is not converting.
+ * @param ADCx: where x can be 1 to select the ADC1 peripheral.
+ * @note The ADC can be powered down:
+ * - During the Auto delay phase: The ADC is powered on again at the end
+ * of the delay (until the previous data is read from the ADC data register).
+ * - During the ADC is waiting for a trigger event: The ADC is powered up
+ * at the next trigger event (when the conversion is started).
+ * @param NewState: new state of the ADCx power Off.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void ADC_AutoPowerOffCmd(ADC_TypeDef* ADCx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the ADC Automatic Power-Off */
+ ADCx->CFGR1 |= ADC_CFGR1_AUTOFF;
+ }
+ else
+ {
+ /* Disable the ADC Automatic Power-Off */
+ ADCx->CFGR1 &= (uint32_t)~ADC_CFGR1_AUTOFF;
+ }
+}
+
+/**
+ * @brief Enables or disables the Wait conversion mode.
+ * @note When the CPU clock is not fast enough to manage the data rate, a
+ * Hardware delay can be introduced between ADC conversions to reduce
+ * this data rate.
+ * @note The Hardware delay is inserted after each conversions and until the
+ * previous data is read from the ADC data register
+ * @note This is a way to automatically adapt the speed of the ADC to the speed
+ * of the system which will read the data.
+ * @note Any hardware triggers wich occur while a conversion is on going or
+ * while the automatic Delay is applied are ignored
+ * @param ADCx: where x can be 1 to select the ADC1 peripheral.
+ * @param NewState: new state of the ADCx Auto-Delay.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void ADC_WaitModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the ADC Automatic Delayed conversion */
+ ADCx->CFGR1 |= ADC_CFGR1_WAIT;
+ }
+ else
+ {
+ /* Disable the ADC Automatic Delayed conversion */
+ ADCx->CFGR1 &= (uint32_t)~ADC_CFGR1_WAIT;
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup ADC_Group3 Analog Watchdog configuration functions
+ * @brief Analog Watchdog configuration functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Analog Watchdog configuration functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to configure the Analog Watchdog
+ (AWD) feature in the ADC.
+ [..] A typical configuration Analog Watchdog is done following these steps :
+ (#) the ADC guarded channel(s) is (are) selected using the
+ ADC_AnalogWatchdogSingleChannelConfig() function.
+ (#) The Analog watchdog lower and higher threshold are configured using the
+ ADC_AnalogWatchdogThresholdsConfig() function.
+ (#) The Analog watchdog is enabled and configured to enable the check, on one
+ or more channels, using the ADC_AnalogWatchdogCmd() function.
+ (#) Enable the analog watchdog on the selected channel using
+ ADC_AnalogWatchdogSingleChannelCmd() function
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the analog watchdog
+ * @param ADCx: where x can be 1 to select the ADC1 peripheral.
+ * @param NewState: new state of the ADCx Analog Watchdog.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void ADC_AnalogWatchdogCmd(ADC_TypeDef* ADCx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the ADC Analog Watchdog */
+ ADCx->CFGR1 |= ADC_CFGR1_AWDEN;
+ }
+ else
+ {
+ /* Disable the ADC Analog Watchdog */
+ ADCx->CFGR1 &= (uint32_t)~ADC_CFGR1_AWDEN;
+ }
+}
+
+/**
+ * @brief Configures the high and low thresholds of the analog watchdog.
+ * @param ADCx: where x can be 1 to select the ADC1 peripheral.
+ * @param HighThreshold: the ADC analog watchdog High threshold value.
+ * This parameter must be a 12bit value.
+ * @param LowThreshold: the ADC analog watchdog Low threshold value.
+ * This parameter must be a 12bit value.
+ * @retval None
+ */
+void ADC_AnalogWatchdogThresholdsConfig(ADC_TypeDef* ADCx, uint16_t HighThreshold,
+ uint16_t LowThreshold)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_THRESHOLD(HighThreshold));
+ assert_param(IS_ADC_THRESHOLD(LowThreshold));
+
+ /* Set the ADCx high and low threshold */
+ ADCx->TR = LowThreshold | ((uint32_t)HighThreshold << 16);
+
+}
+
+/**
+ * @brief Configures the analog watchdog guarded single channel
+ * @param ADCx: where x can be 1 to select the ADC1 peripheral.
+ * @param ADC_AnalogWatchdog_Channel: the ADC channel to configure for the analog watchdog.
+ * This parameter can be one of the following values:
+ * @arg ADC_AnalogWatchdog_Channel_0: ADC Channel0 selected
+ * @arg ADC_AnalogWatchdog_Channel_1: ADC Channel1 selected
+ * @arg ADC_AnalogWatchdog_Channel_2: ADC Channel2 selected
+ * @arg ADC_AnalogWatchdog_Channel_3: ADC Channel3 selected
+ * @arg ADC_AnalogWatchdog_Channel_4: ADC Channel4 selected
+ * @arg ADC_AnalogWatchdog_Channel_5: ADC Channel5 selected
+ * @note The channel selected on the AWDCH must be also set into the CHSELR
+ * register
+ * @retval None
+ */
+void ADC_AnalogWatchdogSingleChannelConfig(ADC_TypeDef* ADCx, uint32_t ADC_AnalogWatchdog_Channel)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_ANALOG_WATCHDOG_CHANNEL(ADC_AnalogWatchdog_Channel));
+
+ /* Get the old register value */
+ tmpreg = ADCx->CFGR1;
+
+ /* Clear the Analog watchdog channel select bits */
+ tmpreg &= ~ADC_CFGR1_AWDCH;
+
+ /* Set the Analog watchdog channel */
+ tmpreg |= ADC_AnalogWatchdog_Channel;
+
+ /* Store the new register value */
+ ADCx->CFGR1 = tmpreg;
+}
+
+/**
+ * @brief Enables or disables the ADC Analog Watchdog Single Channel.
+ * @param ADCx: where x can be 1 to select the ADC1 peripheral.
+ * @param NewState: new state of the ADCx ADC Analog Watchdog Single Channel.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void ADC_AnalogWatchdogSingleChannelCmd(ADC_TypeDef* ADCx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the ADC Analog Watchdog Single Channel */
+ ADCx->CFGR1 |= ADC_CFGR1_AWDSGL;
+ }
+ else
+ {
+ /* Disable the ADC Analog Watchdog Single Channel */
+ ADCx->CFGR1 &= (uint32_t)~ADC_CFGR1_AWDSGL;
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup ADC_Group4 Vrefint functions
+ * @brief Vrefint functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Vrefint function #####
+ ===============================================================================
+ [..] This section provides a function allowing to enable/disable the internal
+ connections between the ADC the Vrefint.
+
+ [..] A typical configuration to get the Vrefint
+ voltages is done following these steps :
+ (#) Enable the internal connection of Vrefint sources
+ with the ADC channels using ADC_VrefintCmd() functions.
+ (#) select the ADC_Channel_5(Vrefint) using ADC_ChannelConfig() function
+ (#) Get the voltage values, using ADC_GetConversionValue() function
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the Vrefint channel.
+ * @param ADCx: where x can be 1 to select the ADC peripheral.
+ * @param NewState: new state of the Vref input channel.
+ * This parameter can be: ENABLE or DISABLE.
+ *..........for voltage value, please reer PWR_VREF_SEL.
+ * @retval None
+ */
+void ADC_VrefintCmd(ADC_TypeDef* ADCx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the Vrefint channel*/
+ ADCx->CCR |= (uint32_t)ADC_CCR_VREFEN;
+ }
+ else
+ {
+ /* Disable the Vrefint channel*/
+ ADCx->CCR &= (uint32_t)(~ADC_CCR_VREFEN);
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup ADC_Group5 Channels Configuration functions
+ * @brief Channels Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Channels Configuration functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to manage the ADC channels,
+ it is composed of 3 sub sections :
+ (#) Configuration and management functions for ADC channels: This subsection
+ provides functions allowing to configure the ADC channels :
+ (++) Select the ADC channels
+ (++) Activate ADC Calibration
+ (++) Activate the Overrun Mode.
+ (++) Activate the Discontinuous Mode
+ (++) Activate the Continuous Mode.
+ (++) Configure the sampling time for each channel
+ (++) Select the conversion Trigger and Edge for ADC channels
+ (++) Select the scan direction.
+ -@@- Please Note that the following features for ADC channels are configurated
+ using the ADC_Init() function :
+ (+@@) Activate the Continuous Mode (can be also activated by ADC_OverrunModeCmd().
+ (+@@) Select the conversion Trigger and Edge for ADC channels
+ (+@@) Select the scan direction.
+ (#) Control the ADC peripheral : This subsection permits to command the ADC:
+ (++) Stop or discard an on-going conversion (ADSTP command)
+ (++) Start the ADC conversion .
+ (#) Get the conversion data: This subsection provides an important function in
+ the ADC peripheral since it returns the converted data of the current
+ ADC channel. When the Conversion value is read, the EOC Flag is
+ automatically cleared.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Configures for the selected ADC and its sampling time.
+ * @param ADCx: where x can be 1 to select the ADC peripheral.
+ * @param ADC_Channel: the ADC channel to configure.
+ * This parameter can be any combination of the following values:
+ * @arg ADC_Channel_0: ADC Channel0 selected
+ * @arg ADC_Channel_1: ADC Channel1 selected
+ * @arg ADC_Channel_2: ADC Channel2 selected
+ * @arg ADC_Channel_3: ADC Channel3 selected
+ * @arg ADC_Channel_4: ADC Channel4 selected
+ * @arg ADC_Channel_5: ADC Channel5 selected
+ * @param ADC_SampleTime: The sample time value to be set for the selected channel.
+ * This parameter can be one of the following values:
+ * @arg ADC_SampleTime_1_5Cycles: Sample time equal to 1.5 cycles
+ * @arg ADC_SampleTime_7_5Cycles: Sample time equal to 7.5 cycles
+ * @arg ADC_SampleTime_13_5Cycles: Sample time equal to 13.5 cycles
+ * @arg ADC_SampleTime_28_5Cycles: Sample time equal to 28.5 cycles
+ * @arg ADC_SampleTime_41_5Cycles: Sample time equal to 41.5 cycles
+ * @arg ADC_SampleTime_55_5Cycles: Sample time equal to 55.5 cycles
+ * @arg ADC_SampleTime_71_5Cycles: Sample time equal to 71.5 cycles
+ * @arg ADC_SampleTime_239_5Cycles: Sample time equal to 239.5 cycles
+ * @retval None
+ */
+void ADC_ChannelConfig(ADC_TypeDef* ADCx, uint32_t ADC_Channel, uint32_t ADC_SampleTime)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_CHANNEL(ADC_Channel));
+ assert_param(IS_ADC_SAMPLE_TIME(ADC_SampleTime));
+
+ /* Configure the ADC Channel */
+ ADCx->CHSELR |= (uint32_t)ADC_Channel;
+
+ /* Clear the Sampling time Selection bits */
+ tmpreg &= ~ADC_SMPR1_SMPR;
+
+ /* Set the ADC Sampling Time register */
+ tmpreg |= (uint32_t)ADC_SampleTime;
+
+ /* Configure the ADC Sample time register */
+ ADCx->SMPR = tmpreg ;
+}
+
+/**
+ * @brief Enable the Continuous mode for the selected ADCx channels.
+ * @param ADCx: where x can be 1 to select the ADC1 peripheral.
+ * @param NewState: new state of the Continuous mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @note It is not possible to have both discontinuous mode and continuous mode
+ * enabled. In this case (If DISCEN and CONT are Set), the ADC behaves
+ * as if continuous mode was disabled
+ * @retval None
+ */
+void ADC_ContinuousModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the Continuous mode*/
+ ADCx->CFGR1 |= (uint32_t)ADC_CFGR1_CONT;
+ }
+ else
+ {
+ /* Disable the Continuous mode */
+ ADCx->CFGR1 &= (uint32_t)(~ADC_CFGR1_CONT);
+ }
+}
+
+/**
+ * @brief Enable the discontinuous mode for the selected ADC channels.
+ * @param ADCx: where x can be 1 to select the ADC1 peripheral.
+ * @param NewState: new state of the discontinuous mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @note It is not possible to have both discontinuous mode and continuous mode
+ * enabled. In this case (If DISCEN and CONT are Set), the ADC behaves
+ * as if continuous mode was disabled
+ * @retval None
+ */
+void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the Discontinuous mode */
+ ADCx->CFGR1 |= (uint32_t)ADC_CFGR1_DISCEN;
+ }
+ else
+ {
+ /* Disable the Discontinuous mode */
+ ADCx->CFGR1 &= (uint32_t)(~ADC_CFGR1_DISCEN);
+ }
+}
+
+/**
+ * @brief Enable the Overrun mode for the selected ADC channels.
+ * @param ADCx: where x can be 1 to select the ADC1 peripheral.
+ * @param NewState: new state of the Overrun mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void ADC_OverrunModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the Overrun mode */
+ ADCx->CFGR1 |= (uint32_t)ADC_CFGR1_OVRMOD;
+ }
+ else
+ {
+ /* Disable the Overrun mode */
+ ADCx->CFGR1 &= (uint32_t)(~ADC_CFGR1_OVRMOD);
+ }
+}
+
+/**
+ * @brief Active the Calibration operation for the selected ADC.
+ * @note The Calibration can be initiated only when ADC is still in the
+ * reset configuration (ADEN must be equal to 0).
+ * @param ADCx: where x can be 1 to select the ADC1 peripheral.
+ * @retval ADC Calibration factor
+ */
+uint32_t ADC_GetCalibrationFactor(ADC_TypeDef* ADCx)
+{
+ uint32_t tmpreg = 0, calibrationcounter = 0, calibrationstatus = 0;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+
+ /* Set the ADC calibartion */
+ ADCx->CR |= (uint32_t)ADC_CR_ADCAL;
+
+ /* Wait until no ADC calibration is completed */
+ do
+ {
+ calibrationstatus = ADCx->CR & ADC_CR_ADCAL;
+ calibrationcounter++;
+ } while((calibrationcounter != CALIBRATION_TIMEOUT) && (calibrationstatus != 0x00));
+
+ if((uint32_t)(ADCx->CR & ADC_CR_ADCAL) == RESET)
+ {
+ /*Get the calibration factor from the ADC data register */
+ tmpreg = ADCx->DR;
+ }
+ else
+ {
+ /* Error factor */
+ tmpreg = 0x00000000;
+ }
+ return tmpreg;
+}
+
+/**
+ * @brief Stop the on going conversions for the selected ADC.
+ * @note When ADSTP is set, any on going conversion is aborted, and the ADC
+ * data register is not updated with current conversion.
+ * @param ADCx: where x can be 1 to select the ADC1 peripheral.
+ * @retval None
+ */
+void ADC_StopOfConversion(ADC_TypeDef* ADCx)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+
+ ADCx->CR |= (uint32_t)ADC_CR_ADSTP;
+}
+
+/**
+ * @brief Start Conversion for the selected ADC channels.
+ * @note In continuous mode, ADSTART is not cleared by hardware with the
+ * assertion of EOSEQ because the sequence is automatic relaunched
+ * @param ADCx: where x can be 1 to select the ADC1 peripheral.
+ * @retval None
+ */
+void ADC_StartOfConversion(ADC_TypeDef* ADCx)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+
+ ADCx->CR |= (uint32_t)ADC_CR_ADSTART;
+}
+
+/**
+ * @brief Returns the last ADCx conversion result data for ADC channel.
+ * @param ADCx: where x can be 1 to select the ADC1 peripheral.
+ * @retval The Data conversion value.
+ */
+uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+
+ /* Return the selected ADC conversion value */
+ return (uint16_t) ADCx->DR;
+}
+
+
+/** @defgroup ADC_Group7 Interrupts and flags management functions
+ * @brief Interrupts and flags management functions.
+ *
+@verbatim
+ ===============================================================================
+ ##### Interrupts and flags management functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to configure the ADC Interrupts
+ and get the status and clear flags and Interrupts pending bits.
+
+ [..] The ADC provide 6 Interrupts sources and 11 Flags which can be divided into
+ 3 groups:
+
+ *** Flags for ADC status ***
+ ======================================================
+ [..]
+ (+)Flags :
+ (##) ADC_FLAG_ADRDY : This flag is set after the ADC has been enabled (bit ADEN=1)
+ and when the ADC reaches a state where it is ready to accept conversion requests
+ (##) ADC_FLAG_ADEN : This flag is set by software to enable the ADC.
+ The ADC will be effectively ready to operate once the ADRDY flag has been set.
+ (##) ADC_FLAG_ADDIS : This flag is cleared once the ADC is effectively
+ disabled.
+ (##) ADC_FLAG_ADSTART : This flag is cleared after the execution of
+ ADC_StopOfConversion() function, at the same time as the ADSTP bit is
+ cleared by hardware
+ (##) ADC_FLAG_ADSTP : This flag is cleared by hardware when the conversion
+ is effectively discarded and the ADC is ready to accept a new start conversion
+ (##) ADC_FLAG_ADCAL : This flag is set once the calibration is complete.
+
+ (+)Interrupts
+ (##) ADC_IT_ADRDY : specifies the interrupt source for ADC ready event.
+
+ *** Flags and Interrupts for ADC channel conversion ***
+ =====================================================
+ [..]
+ (+)Flags :
+ (##) ADC_FLAG_EOC : This flag is set by hardware at the end of each conversion
+ of a channel when a new data result is available in the data register
+ (##) ADC_FLAG_EOSEQ : This bit is set by hardware at the end of the conversion
+ of a sequence of channels selected by ADC_ChannelConfig() function.
+ (##) ADC_FLAG_EOSMP : This bit is set by hardware at the end of the sampling phase.
+ (##) ADC_FLAG_OVR : This flag is set by hardware when an overrun occurs,
+ meaning that a new conversion has complete while the EOC flag was already set.
+
+ (+)Interrupts :
+ (##) ADC_IT_EOC : specifies the interrupt source for end of conversion event.
+ (##) ADC_IT_EOSEQ : specifies the interrupt source for end of sequence event.
+ (##) ADC_IT_EOSMP : specifies the interrupt source for end of sampling event.
+ (##) ADC_IT_OVR : specifies the interrupt source for Overrun detection
+ event.
+
+ *** Flags and Interrupts for the Analog Watchdog ***
+ ================================================
+ [..]
+ (+)Flags :
+ (##) ADC_FLAG_AWD: This flag is set by hardware when the converted
+ voltage crosses the values programmed thrsholds
+
+ (+)Interrupts :
+ (##) ADC_IT_AWD : specifies the interrupt source for Analog watchdog
+ event.
+
+ [..] The user should identify which mode will be used in his application to
+ manage the ADC controller events: Polling mode or Interrupt mode.
+
+ [..] In the Polling Mode it is advised to use the following functions:
+ (+) ADC_GetFlagStatus() : to check if flags events occur.
+ (+) ADC_ClearFlag() : to clear the flags events.
+
+ [..] In the Interrupt Mode it is advised to use the following functions:
+ (+) ADC_ITConfig() : to enable or disable the interrupt source.
+ (+) ADC_GetITStatus() : to check if Interrupt occurs.
+ (+) ADC_ClearITPendingBit() : to clear the Interrupt pending Bit
+ (corresponding Flag).
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the specified ADC interrupts.
+ * @param ADCx: where x can be 1 to select the ADC peripheral.
+ * @param ADC_IT: specifies the ADC interrupt sources to be enabled or disabled.
+ * This parameter can be one of the following values:
+ * @arg ADC_IT_ADRDY: ADC ready interrupt
+ * @arg ADC_IT_EOSMP: End of sampling interrupt
+ * @arg ADC_IT_EOC: End of conversion interrupt
+ * @arg ADC_IT_EOSEQ: End of sequence of conversion interrupt
+ * @arg ADC_IT_OVR: overrun interrupt
+ * @arg ADC_IT_AWD: Analog watchdog interrupt
+ * @param NewState: new state of the specified ADC interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void ADC_ITConfig(ADC_TypeDef* ADCx, uint32_t ADC_IT, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ assert_param(IS_ADC_CONFIG_IT(ADC_IT));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected ADC interrupts */
+ ADCx->IER |= ADC_IT;
+ }
+ else
+ {
+ /* Disable the selected ADC interrupts */
+ ADCx->IER &= (~(uint32_t)ADC_IT);
+ }
+}
+
+/**
+ * @brief Checks whether the specified ADC flag is set or not.
+ * @param ADCx: where x can be 1 to select the ADC1 peripheral.
+ * @param ADC_FLAG: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg ADC_FLAG_AWD: Analog watchdog flag
+ * @arg ADC_FLAG_OVR: Overrun flag
+ * @arg ADC_FLAG_EOSEQ: End of Sequence flag
+ * @arg ADC_FLAG_EOC: End of conversion flag
+ * @arg ADC_FLAG_EOSMP: End of sampling flag
+ * @arg ADC_FLAG_ADRDY: ADC Ready flag
+ * @arg ADC_FLAG_ADEN: ADC enable flag
+ * @arg ADC_FLAG_ADDIS: ADC disable flag
+ * @arg ADC_FLAG_ADSTART: ADC start flag
+ * @arg ADC_FLAG_ADSTP: ADC stop flag
+ * @arg ADC_FLAG_ADCAL: ADC Calibration flag
+ * @retval The new state of ADC_FLAG (SET or RESET).
+ */
+FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint32_t ADC_FLAG)
+{
+ FlagStatus bitstatus = RESET;
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_GET_FLAG(ADC_FLAG));
+
+ if((uint32_t)(ADC_FLAG & 0x01000000))
+ {
+ tmpreg = ADCx->CR & 0xFEFFFFFF;
+ }
+ else
+ {
+ tmpreg = ADCx->ISR;
+ }
+
+ /* Check the status of the specified ADC flag */
+ if ((tmpreg & ADC_FLAG) != (uint32_t)RESET)
+ {
+ /* ADC_FLAG is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* ADC_FLAG is reset */
+ bitstatus = RESET;
+ }
+ /* Return the ADC_FLAG status */
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the ADCx's pending flags.
+ * @param ADCx: where x can be 1 to select the ADC1 peripheral.
+ * @param ADC_FLAG: specifies the flag to clear.
+ * This parameter can be any combination of the following values:
+ * @arg ADC_FLAG_AWD: Analog watchdog flag
+ * @arg ADC_FLAG_EOC: End of conversion flag
+ * @arg ADC_FLAG_ADRDY: ADC Ready flag
+ * @arg ADC_FLAG_EOSMP: End of sampling flag
+ * @arg ADC_FLAG_EOSEQ: End of Sequence flag
+ * @arg ADC_FLAG_OVR: Overrun flag
+ * @retval None
+ */
+void ADC_ClearFlag(ADC_TypeDef* ADCx, uint32_t ADC_FLAG)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_CLEAR_FLAG(ADC_FLAG));
+
+ /* Clear the selected ADC flags */
+ ADCx->ISR = (uint32_t)ADC_FLAG;
+}
+
+/**
+ * @brief Checks whether the specified ADC interrupt has occurred or not.
+ * @param ADCx: where x can be 1 to select the ADC1 peripheral
+ * @param ADC_IT: specifies the ADC interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg ADC_IT_ADRDY: ADC ready interrupt
+ * @arg ADC_IT_EOSMP: End of sampling interrupt
+ * @arg ADC_IT_EOC: End of conversion interrupt
+ * @arg ADC_IT_EOSEQ: End of sequence of conversion interrupt
+ * @arg ADC_IT_OVR: overrun interrupt
+ * @arg ADC_IT_AWD: Analog watchdog interrupt
+ * @retval The new state of ADC_IT (SET or RESET).
+ */
+ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint32_t ADC_IT)
+{
+ ITStatus bitstatus = RESET;
+ uint32_t enablestatus = 0;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_GET_IT(ADC_IT));
+
+ /* Get the ADC_IT enable bit status */
+ enablestatus = (uint32_t)(ADCx->IER & ADC_IT);
+
+ /* Check the status of the specified ADC interrupt */
+ if (((uint32_t)(ADCx->ISR & ADC_IT) != (uint32_t)RESET) && (enablestatus != (uint32_t)RESET))
+ {
+ /* ADC_IT is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* ADC_IT is reset */
+ bitstatus = RESET;
+ }
+ /* Return the ADC_IT status */
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the ADCx's interrupt pending bits.
+ * @param ADCx: where x can be 1 to select the ADC1 peripheral.
+ * @param ADC_IT: specifies the ADC interrupt pending bit to clear.
+ * This parameter can be one of the following values:
+ * @arg ADC_IT_ADRDY: ADC ready interrupt
+ * @arg ADC_IT_EOSMP: End of sampling interrupt
+ * @arg ADC_IT_EOC: End of conversion interrupt
+ * @arg ADC_IT_EOSEQ: End of sequence of conversion interrupt
+ * @arg ADC_IT_OVR: overrun interrupt
+ * @arg ADC_IT_AWD: Analog watchdog interrupt
+ * @retval None
+ */
+void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint32_t ADC_IT)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_CLEAR_IT(ADC_IT));
+
+ /* Clear the selected ADC interrupt pending bits */
+ ADCx->ISR = (uint32_t)ADC_IT;
+}
+
+/**
+ * @brief enable or disable AWD wake up.
+ * @param ADCx: where x can be 1 to select the ADC1 peripheral.
+ * @param NewState: new state of the specified ADC interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ *note
+ enable AWD first
+ close continue mode
+ close disconnect mode
+ clear AWD flag after deal
+ * @retval None
+ */
+void ADC_AWDWakeup_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ /* set or reset AWD wakeup function in stop*/
+
+ if(NewState != DISABLE)
+ ADCx->CR2 |= (uint32_t)ADC_CR2_WAKE_EN;
+ else
+ ADCx->CR2 &= (~(uint32_t)ADC_CR2_WAKE_EN);
+}
+
+/**
+ * @}
+ */
+/**
+ * @brief enable or disable AWD Differential input mode.
+ * @param ADCx: where x can be 1 to select the ADC1 peripheral.
+ * @param NewState: new state of the specified ADC interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void ADC_Diff_Func(ADC_TypeDef* ADCx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if(NewState != DISABLE)
+ ADCx->CR2 |= ADC_CR2_SDIF;
+ else
+ ADCx->CR2 &= (~(uint32_t)ADC_CR2_SDIF);
+}
+/**
+ * @}
+ */
+/**
+ * @brief enable or disable AWD internal delay function.
+ * @param ADCx: where x can be 1 to select the ADC1 peripheral.
+ * @param NewState: new state of the specified ADC interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void ADC_InterDelay_Func(ADC_TypeDef* ADCx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if(NewState != DISABLE)
+ ADCx->CR2 |= ADC_CR2_GCMP;
+ else
+ ADCx->CR2 &= (~(uint32_t)ADC_CR2_GCMP);
+}
+
+/**
+ * @}
+ */
+
+
+
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_awu.c b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_awu.c
new file mode 100644
index 0000000..90d1d87
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_awu.c
@@ -0,0 +1,105 @@
+/**
+ ******************************************************************************
+ * @file hk32f030m_awu.c
+ * @author Rakan.z
+ * @version V1.0
+ * @brief This file contains all the functions for the AWU peripheral.
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "hk32f030m_awu.h"
+/* Public functions ----------------------------------------------------------*/
+
+/**
+ * @addtogroup AWU_Public_Functions
+ * @{
+ */
+
+/**
+ * @brief Deinitializes the AWU peripheral registers to their default reset
+ * values.
+ * @param None
+ * @retval None
+ */
+void AWU_DeInit(void)
+{
+ AWU->CR = AWU_CR_RESET_VALUE;
+ AWU->SR = AWU_SR_RESET_VALUE;
+}
+
+/**
+ * @brief config the AWU clock
+ * @param eAWU_CLK :
+ * AWU_CLK_LSI128
+ AWU_CLK_HSE
+ * @retval None
+ * @par Required preconditions:
+ * The LS RC calibration must be performed before calling this function.
+ */
+void AWU_CLKConfig(AWU_CLK_TYPE eAWU_CLK)
+{
+ uint32_t temp = 0;
+ /* Check parameter */
+ assert_param(IS_AWU_CLK(eAWU_CLK));
+
+ temp = AWU->CR;
+ /*clear Bit AWU_CKSEL*/
+ temp &= 0xFFFFFFFE;
+ /* config AWU timer clk*/
+ temp |= eAWU_CLK;
+ /*set the register*/
+ AWU->CR |= temp;
+}
+
+/**
+ * @brief loade the AWU timer counter,This load value will be automatically loaded into the 22-bit timer inside the awu
+ * when the mcu enters stop mode and start timing.
+ * @param TimerCounter : the AWU timer counter
+ * @note When awu_rlr [22:1] is '0' or is '1' , the loading behavior will not occur and awu will not start working .
+ * when awu_wbusy =1 ,the write operation on the awu-rlr register will be invalid.
+ * @return ErrorStatus: the AWU result
+ * SUCCESS:AWU timer start success
+ * ERRORAWU timer start error
+ */
+ErrorStatus AWU_TimerCounterAndStart(uint32_t TimerCounter)
+{
+ uint32_t temp = 0;
+ uint32_t TimeoutCnt = 0;
+ while (TimeoutCnt ++ <= 0x0fff)
+ {
+ // AWU_APB bus is idle
+ if ((AWU->CR & 0x80000000) == 0x00000000)
+ {
+ temp = AWU->CR;
+ temp &= 0xFF800001;
+ temp |= ( TimerCounter << 1);
+ AWU->CR |= temp;
+ return SUCCESS;
+ }
+ else
+ {
+ /* when awu_wbusy =1 ,the write operation on the awu-rlr register will be invalid.*/
+ }
+ }
+
+ return ERROR;
+
+}
+
+/**
+ * @brief Returns status of the AWU peripheral flag.
+ * @param None
+ * @retval FlagStatus : Status of the AWU flag.
+ * This parameter can be any of the @ref FlagStatus enumeration.
+ */
+FlagStatus AWU_GetFlagStatus(void)
+{
+ return((FlagStatus)(((uint8_t)(AWU->SR & AWU_SR_BUSY) == (uint8_t)0x00) ? RESET : SET));
+}
+
+
+/**
+ * @}
+ */
+
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_beep.c b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_beep.c
new file mode 100644
index 0000000..80705d1
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_beep.c
@@ -0,0 +1,226 @@
+
+/**
+ ******************************************************************************
+ * @file hk32f030m_beep.c
+ * @version V1.0.1
+ * author Rakan.Z/wing.Wang
+ * @date 2019-12-15
+ ******************************************************************************
+ */
+
+#include "hk32f030m_beep.h"
+#include "hk32f030m.h"
+
+
+
+/**
+ * @brief Initialize the beeper peripheral register to the default
+ * value reset value
+ * @param None
+ * @retval None
+ */
+
+
+void BEEP_DeInit(void)
+{
+ /*BEEP clock:LSI,BEEP_Prescaler:64,BEEP_TRGO_Prescaler:64*/
+ BEEP->CFGR = BEEP_CFGR_Value;
+ /*BEEP:ENABLE,TRGO:ENABLE*/
+ while(BEEP->CR & BEEP_BUSY_FLAG);
+ BEEP->CR |= BEEP_CR_Value;
+}
+
+/**
+ * @brief Initialize the BEEP peripheral register
+ * @param BEEP_InitStruct:pointer to a BEEP_InitTypeDef structure which will be initialized.
+ * @retval None
+ */
+void BEEP_Init(BEEP_InitTypeDef *BEEP_InitStruct)
+{
+ assert_param(IS_BEEP_CLOCK(BEEP_InitStruct->BEEP_Clock));
+ assert_param(IS_BEEP_TRGO_PRESCALER(BEEP_InitStruct->BEEP_TRGOPrescaler));
+ assert_param(IS_BEEP_PRESCALER(BEEP_InitStruct->BEEP_Prescaler));
+ assert_param(IS_FUNCTIONAL_STATE(BEEP_InitStruct->BEEP_TRGOCmd));
+
+ uint32_t temp=0;
+ /*Set the BEEP clock*/
+ if(BEEP_InitStruct->BEEP_Clock == BEEP_CLOCK_HSE)
+ {
+ BEEP->CFGR |= BEEP_CLOCK_HSE;
+ }
+ else
+ {
+ BEEP->CFGR &= ~(BEEP_CLOCK_HSE);
+ }
+
+
+ /*Clear [2:1]bits*/
+ temp = BEEP->CFGR;
+
+ temp &= BEEP_CR_BEEP_Mask;
+ /*Set the frequency division coefficient*/
+ temp |= BEEP_InitStruct->BEEP_Prescaler;
+ /*To transfer a value into a register*/
+ BEEP->CFGR = temp;
+
+ /*Clear [4:3]bits*/
+ temp &= BEEP_CR_TRGO_Mask;
+ /*Set the frequency division coefficient*/
+ temp |= BEEP_InitStruct->BEEP_TRGOPrescaler;
+
+ /*To transfer a value into a register*/
+ BEEP->CFGR = temp;
+
+ /*Enable or disable TRGO*/
+ if(BEEP_InitStruct->BEEP_TRGOCmd)
+ {
+ while(BEEP->CR & BEEP_BUSY_FLAG);
+ BEEP->CR |= BEEP_CR_TRGO;
+ }
+ else
+ {
+ while(BEEP->CR & BEEP_BUSY_FLAG);
+ BEEP->CR &= (uint32_t)~((uint32_t)BEEP_CR_TRGO);
+ }
+}
+
+/**
+ * @brief Enables or disables the specified BEEP peripheral.
+ * @param NewState:new state of the BEEP peripheral.
+ * @retval None
+ */
+void BEEP_Cmd(FunctionalState NewState)
+{
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if(NewState != DISABLE)
+ {
+ /*Enable BEEP*/
+ while(BEEP->CR & BEEP_BUSY_FLAG);
+ BEEP->CR |= BEEP_CR_EN;
+ }
+ else
+ {
+ /*Disable BEEP*/
+ while(BEEP->CR & BEEP_BUSY_FLAG);
+ BEEP->CR &= (uint32_t)~((uint32_t)BEEP_CR_EN);
+ }
+}
+
+
+/**
+ * @brief Select the BEEP clock.
+ * @param BEEP_CLOCK: Clock source selection.
+ * This parameter can be one of the following values:
+ * @arg BEEP_CLOCK_HSE
+ * @arg BEEP_CLOCK_LSI
+ * @retval None
+ */
+void BEEP_ClockSelect(uint8_t BEEP_CLOCK)
+{
+ assert_param(IS_BEEP_CLOCK(BEEP_CLOCK));
+ if(BEEP_CLOCK_HSE == BEEP_CLOCK)
+ {
+ /*Set HSE as the clock source*/
+ BEEP->CFGR |= BEEP_CLOCK_HSE;
+ }
+ else
+ {
+ /*Set LSI as the clock source*/
+ BEEP->CFGR &= ~(BEEP_CLOCK_HSE);
+ }
+}
+
+
+/**
+ * @brief Set the BEEP frequency division coefficient.
+ * @param BEEP_Prescaler: frequency division coefficient selection.
+ * This parameter can be one of the following values:
+ * @arg BEEP_Prescaler_16
+ * @arg BEEP_Prescaler_32
+ * @arg BEEP_Prescaler_64
+ * @arg BEEP_Prescaler_128
+ * @retval None
+ */
+void BEEP_SetPrescaler(uint8_t BEEP_Prescaler)
+{
+ uint32_t temp = 0;
+ assert_param(IS_BEEP_PRESCALER(BEEP_Prescaler));
+
+ /*Clear [2:1]bits*/
+ temp = BEEP->CFGR;
+ temp &= BEEP_CR_BEEP_Mask;
+ /*Set the frequency division coefficient*/
+ temp |= BEEP_Prescaler;
+ /*To transfer a value into a register*/
+ BEEP->CFGR = temp;
+}
+
+
+
+/**
+ * @brief Set the TGRO frequency division coefficient.
+ * @param BEEP_TGRO_Prescaler: frequency division coefficient selection.
+ * This parameter can be one of the following values:
+ * @arg BEEP_TRGO_Prescaler_32
+ * @arg BEEP_TRGO_Prescaler_64
+ * @arg BEEP_TRGO_Prescaler_128
+ * @retval None
+ */
+void BEEP_SetTRGOPrescaler(uint8_t BEEP_TRGO_Prescaler)
+{
+ uint32_t temp=0;
+ assert_param(IS_BEEP_TRGO_PRESCALER(BEEP_TRGO_Prescaler));
+
+ /*Clear [4:3]bits*/
+ temp = BEEP->CFGR;
+ temp &= BEEP_CR_TRGO_Mask;
+ /*Set the frequency division coefficient*/
+ temp |= BEEP_TRGO_Prescaler;
+ /*To transfer a value into a register*/
+ BEEP->CFGR = temp;
+}
+
+
+/**
+ * @brief Read BEEP register status.
+ * @param None
+ * @retval register status
+ */
+FlagStatus BEEP_ReadBeepStatus(void)
+{
+ if((BEEP->CR & (BEEP_BUSY_FLAG)) == BEEP_BUSY_FLAG)
+ {
+ return SET;
+ }
+ else
+ {
+ return RESET;
+ }
+}
+
+
+/**
+ * @brief Enables or disables the TRGO function.
+ * @param NewState:new state of the BEEP peripheral.
+ * @retval None
+ */
+void BEEP_TRGOCmd(FunctionalState NewState)
+{
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if(NewState)
+ {
+ /*Enable TRGO*/
+ while(BEEP->CR & BEEP_BUSY_FLAG);
+ BEEP->CR |= (uint32_t)BEEP_CR_TRGO;
+ }
+ else
+ {
+ /*Disable TRGO*/
+ while(BEEP->CR & BEEP_BUSY_FLAG);
+ BEEP->CR &= (uint32_t)~((uint32_t)BEEP_CR_TRGO);
+ }
+}
+
+
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_crc.c b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_crc.c
new file mode 100644
index 0000000..fdfe49f
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_crc.c
@@ -0,0 +1,191 @@
+/**
+ ******************************************************************************
+ * @file hk32f030m_crc.c
+ * @author Rakan.Z/Thomas.W
+ * @version V1.0
+ * @brief API file of CRC module
+ * @changelist
+ ******************************************************************************
+ */
+
+/**
+ ===============================================================================
+ ##### How to use this driver #####
+ ===============================================================================
+ [..]
+
+ (+) Enable CRC AHB clock using RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC, ENABLE)
+ function
+ (+) If required, select the reverse operation on input data
+ using CRC_ReverseInputDataSelect()
+ (+) If required, enable the reverse operation on output data
+ using CRC_ReverseOutputDataCmd(Enable)
+ (+) use CRC_CalcCRC() function to compute the CRC of a 32-bit data
+ or use CRC_CalcBlockCRC() function to compute the CRC if a 32-bit
+ data buffer
+ (@) To compute the CRC of a new data use CRC_ResetDR() to reset
+ the CRC computation unit before starting the computation
+ otherwise you can get wrong CRC values.
+
+ @endverbatim
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "hk32f030m_crc.h"
+
+/**
+ * @brief Deinitializes CRC peripheral registers to their default reset values.
+ * @param None
+ * @retval None
+ */
+void CRC_DeInit(void)
+{
+ /* Set DR register to reset value */
+ CRC->DR = 0xFFFFFFFF;
+
+ /* Reset IDR register */
+ CRC->IDR = 0x00;
+
+ /* Set INIT register to reset value */
+ CRC->INIT = 0xFFFFFFFF;
+
+ /* Reset the CRC calculation unit */
+ CRC->CR = CRC_CR_RESET;
+}
+
+/**
+ * @brief Resets the CRC calculation unit and sets INIT register content in DR register.
+ * @param None
+ * @retval None
+ */
+void CRC_ResetDR(void)
+{
+ /* Reset CRC generator */
+ CRC->CR |= CRC_CR_RESET;
+}
+
+
+/**
+ * @brief Selects the reverse operation to be performed on input data.
+ * @param CRC_ReverseInputData: Specifies the reverse operation on input data.
+ * This parameter can be:
+ * @arg CRC_ReverseInputData_No: No reverse operation is performed
+ * @arg CRC_ReverseInputData_8bits: reverse operation performed on 8 bits
+ * @arg CRC_ReverseInputData_16bits: reverse operation performed on 16 bits
+ * @arg CRC_ReverseInputData_32bits: reverse operation performed on 32 bits
+ * @retval None
+ */
+void CRC_ReverseInputDataSelect(uint32_t CRC_ReverseInputData)
+{
+ uint32_t tmpcr = 0;
+
+ /* Check the parameter */
+ assert_param(IS_CRC_REVERSE_INPUT_DATA(CRC_ReverseInputData));
+
+ /* Get CR register value */
+ tmpcr = CRC->CR;
+
+ /* Reset REV_IN bits */
+ tmpcr &= (uint32_t)~((uint32_t)CRC_CR_REV_IN);
+ /* Set the reverse operation */
+ tmpcr |= (uint32_t)CRC_ReverseInputData;
+
+ /* Write to CR register */
+ CRC->CR = (uint32_t)tmpcr;
+}
+
+/**
+ * @brief Enables or disable the reverse operation on output data.
+ * The reverse operation on output data is performed on 32-bit.
+ * @param NewState: new state of the reverse operation on output data.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void CRC_ReverseOutputDataCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable reverse operation on output data */
+ CRC->CR |= CRC_CR_REV_OUT;
+ }
+ else
+ {
+ /* Disable reverse operation on output data */
+ CRC->CR &= (uint32_t)~((uint32_t)CRC_CR_REV_OUT);
+ }
+}
+
+/**
+ * @brief Initializes the INIT register.
+ * @note After resetting CRC calculation unit, CRC_InitValue is stored in DR register
+ * @param CRC_InitValue: Programmable initial CRC value
+ * @retval None
+ */
+void CRC_SetInitRegister(uint32_t CRC_InitValue)
+{
+ CRC->INIT = CRC_InitValue;
+}
+
+/**
+ * @brief Computes the 32-bit CRC of a given data word(32-bit).
+ * @param CRC_Data: data word(32-bit) to compute its CRC
+ * @retval 32-bit CRC
+ */
+uint32_t CRC_CalcCRC(uint32_t CRC_Data)
+{
+ CRC->DR = CRC_Data;
+
+ return (CRC->DR);
+}
+
+/**
+ * @brief Computes the 32-bit CRC of a given buffer of data word(32-bit).
+ * @param pBuffer: pointer to the buffer containing the data to be computed
+ * @param BufferLength: length of the buffer to be computed
+ * @retval 32-bit CRC
+ */
+uint32_t CRC_CalcBlockCRC(uint32_t pBuffer[], uint32_t BufferLength)
+{
+ uint32_t index = 0;
+
+ for(index = 0; index < BufferLength; index++)
+ {
+ CRC->DR = pBuffer[index];
+ }
+ return (CRC->DR);
+}
+
+/**
+ * @brief Returns the current CRC value.
+ * @param None
+ * @retval 32-bit CRC
+ */
+uint32_t CRC_GetCRC(void)
+{
+ return (CRC->DR);
+}
+
+/**
+ * @brief Stores an 8-bit data in the Independent Data(ID) register.
+ * @param CRC_IDValue: 8-bit value to be stored in the ID register
+ * @retval None
+ */
+void CRC_SetIDRegister(uint8_t CRC_IDValue)
+{
+ CRC->IDR = CRC_IDValue;
+}
+
+/**
+ * @brief Returns the 8-bit data stored in the Independent Data(ID) register
+ * @param None
+ * @retval 8-bit value of the ID register
+ */
+uint8_t CRC_GetIDRegister(void)
+{
+ return (CRC->IDR);
+}
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_dbgmcu.c b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_dbgmcu.c
new file mode 100644
index 0000000..3f11a9b
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_dbgmcu.c
@@ -0,0 +1,96 @@
+/**
+ ******************************************************************************
+ * @file hk32f030m_dbgmcu.c
+ * @author Felix.z
+ * @version V1.0
+ * @brief API file of DBGMCU module
+ * @changelist
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "hk32f030m_dbgmcu.h"
+
+
+#define IDCODE_DEVID_MASK ((uint32_t)0x00000FFF)
+
+
+/**
+ * @brief Returns the device revision identifier.
+ * @param None
+ * @retval Device revision identifier
+ */
+uint32_t DBGMCU_GetREVID(void)
+{
+ return(DBGMCU->IDCODE >> 16);
+}
+
+/**
+ * @brief Returns the device identifier.
+ * @param None
+ * @retval Device identifier
+ */
+uint32_t DBGMCU_GetDEVID(void)
+{
+ return(DBGMCU->IDCODE & IDCODE_DEVID_MASK);
+}
+
+
+/**
+ * @brief Configures low power mode behavior when the MCU is in Debug mode.
+ * @param DBGMCU_Periph: specifies the low power mode.
+ * This parameter can be any combination of the following values:
+ * @arg DBGMCU_STOP: Keep debugger connection during STOP mode
+ * @param NewState: new state of the specified low power mode in Debug mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void DBGMCU_Config(uint32_t DBGMCU_Periph, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_DBGMCU_PERIPH(DBGMCU_Periph));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ DBGMCU->CR |= DBGMCU_Periph;
+ }
+ else
+ {
+ DBGMCU->CR &= ~DBGMCU_Periph;
+ }
+}
+
+
+/**
+ * @brief Configures APB1 peripheral behavior when the MCU is in Debug mode.
+ * @param DBGMCU_Periph: specifies the APB1 peripheral.
+ * This parameter can be any combination of the following values:
+ * @arg DBGMCU_TIM1_STOP: TIM1 counter stopped when Core is halted
+ * @arg DBGMCU_TIM2_STOP: TIM2 counter stopped when Core is halted
+ * @arg DBGMCU_TIM6_STOP: TIM6 counter stopped when Core is halted
+ * @arg DBGMCU_WWDG_STOP: Debug WWDG stopped when Core is halted
+ * @arg DBGMCU_IWDG_STOP: Debug IWDG stopped when Core is halted
+ * @arg DBGMCU_I2C1_SMBUS_TIMEOUT: I2C1 SMBUS timeout mode stopped
+ * when Core is halted
+ * @param NewState: new state of the specified APB1 peripheral in Debug mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void DBGMCU_APB1PeriphConfig(uint32_t DBGMCU_Periph, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_DBGMCU_APB1PERIPH(DBGMCU_Periph));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ DBGMCU->APB1FZ |= DBGMCU_Periph;
+ }
+ else
+ {
+ DBGMCU->APB1FZ &= ~DBGMCU_Periph;
+ }
+}
+
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_exti.c b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_exti.c
new file mode 100644
index 0000000..5fb1fb3
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_exti.c
@@ -0,0 +1,192 @@
+/**
+ ******************************************************************************
+ * @file hk32f030m_exti.c
+ * @author Rakan.z
+ * @version V1.0
+ * @brief API file of BKP module,This file provides all the EXTI firmware functions
+ * @changelist
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "hk32f030m_exti.h"
+
+/** EXTI_Private_Defines */
+
+#define EXTI_LINENONE ((uint32_t)0x00000) /* No interrupt selected */
+
+/**
+ * @brief Deinitializes the EXTI peripheral registers to their default reset values.
+ * @param None
+ * @retval None
+ */
+void EXTI_DeInit(void)
+{
+ EXTI->IMR = 0x00000000;
+ EXTI->EMR = 0x00000000;
+ EXTI->RTSR = 0x00000000;
+ EXTI->FTSR = 0x00000000;
+ EXTI->PR = 0xFFFFFFFF;
+}
+
+/**
+ * @brief Initializes the EXTI peripheral according to the specified
+ * parameters in the EXTI_InitStruct.
+ * @param EXTI_InitStruct: pointer to a EXTI_InitTypeDef structure
+ * that contains the configuration information for the EXTI peripheral.
+ * @retval None
+ */
+void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct)
+{
+ uint32_t tmp = 0;
+
+ /* Check the parameters */
+ assert_param(IS_EXTI_MODE(EXTI_InitStruct->EXTI_Mode));
+ assert_param(IS_EXTI_TRIGGER(EXTI_InitStruct->EXTI_Trigger));
+ assert_param(IS_EXTI_LINE(EXTI_InitStruct->EXTI_Line));
+ assert_param(IS_FUNCTIONAL_STATE(EXTI_InitStruct->EXTI_LineCmd));
+
+ tmp = (uint32_t)EXTI_BASE;
+
+ if (EXTI_InitStruct->EXTI_LineCmd != DISABLE)
+ {
+ /* Clear EXTI line configuration */
+ EXTI->IMR &= ~EXTI_InitStruct->EXTI_Line;
+ EXTI->EMR &= ~EXTI_InitStruct->EXTI_Line;
+
+ tmp += EXTI_InitStruct->EXTI_Mode;
+
+ *(__IO uint32_t *) tmp |= EXTI_InitStruct->EXTI_Line;
+
+ /* Clear Rising Falling edge configuration */
+ EXTI->RTSR &= ~EXTI_InitStruct->EXTI_Line;
+ EXTI->FTSR &= ~EXTI_InitStruct->EXTI_Line;
+
+ /* Select the trigger for the selected external interrupts */
+ if (EXTI_InitStruct->EXTI_Trigger == EXTI_Trigger_Rising_Falling)
+ {
+ /* Rising Falling edge */
+ EXTI->RTSR |= EXTI_InitStruct->EXTI_Line;
+ EXTI->FTSR |= EXTI_InitStruct->EXTI_Line;
+ }
+ else
+ {
+ tmp = (uint32_t)EXTI_BASE;
+ tmp += EXTI_InitStruct->EXTI_Trigger;
+
+ *(__IO uint32_t *) tmp |= EXTI_InitStruct->EXTI_Line;
+ }
+ }
+ else
+ {
+ tmp += EXTI_InitStruct->EXTI_Mode;
+
+ /* Disable the selected external lines */
+ *(__IO uint32_t *) tmp &= ~EXTI_InitStruct->EXTI_Line;
+ }
+}
+
+/**
+ * @brief Fills each EXTI_InitStruct member with its reset value.
+ * @param EXTI_InitStruct: pointer to a EXTI_InitTypeDef structure which will
+ * be initialized.
+ * @retval None
+ */
+void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct)
+{
+ EXTI_InitStruct->EXTI_Line = EXTI_LINENONE;
+ EXTI_InitStruct->EXTI_Mode = EXTI_Mode_Interrupt;
+ EXTI_InitStruct->EXTI_Trigger = EXTI_Trigger_Falling;
+ EXTI_InitStruct->EXTI_LineCmd = DISABLE;
+}
+
+/**
+ * @brief Generates a Software interrupt.
+ * @param EXTI_Line: specifies the EXTI lines to be enabled or disabled.
+ * This parameter can be any combination of EXTI_Linex where x can be (0..11).
+ * @retval None
+ */
+void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line)
+{
+ /* Check the parameters */
+ assert_param(IS_EXTI_LINE(EXTI_Line));
+
+ EXTI->SWIER |= EXTI_Line;
+}
+
+/**
+ * @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:
+ * @arg EXTI_Linex: External interrupt line x where x(0..11)
+ * @retval The new state of EXTI_Line (SET or RESET).
+ */
+FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line)
+{
+ FlagStatus bitstatus = RESET;
+ /* Check the parameters */
+ assert_param(IS_GET_EXTI_LINE(EXTI_Line));
+
+ if ((EXTI->PR & EXTI_Line) != (uint32_t)RESET)
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+ return bitstatus;
+}
+
+/**
+ * @brief Checks whether the specified EXTI line is asserted or not.
+ * @param EXTI_Line: specifies the EXTI line to check.
+ * This parameter can be:
+ * @arg EXTI_Linex: External interrupt line x where x(0..11)
+ * @retval The new state of EXTI_Line (SET or RESET).
+ */
+ITStatus EXTI_GetITStatus(uint32_t EXTI_Line)
+{
+ ITStatus bitstatus = RESET;
+ uint32_t enablestatus = 0;
+ /* Check the parameters */
+ assert_param(IS_GET_EXTI_LINE(EXTI_Line));
+
+ enablestatus = EXTI->IMR & EXTI_Line;
+ if (((EXTI->PR & EXTI_Line) != (uint32_t)RESET) && (enablestatus != (uint32_t)RESET))
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the EXTI's line Flag.
+ * @param EXTI_Line: specifies the EXTI lines to clear.
+ * This parameter can be any combination of EXTI_Linex where x can be (0..11).
+ * @retval None
+ */
+void EXTI_ClearFlag(uint32_t EXTI_Line)
+{
+ /* Check the parameters */
+ assert_param(IS_EXTI_LINE(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 EXTI_Linex where x can be (0..11).
+ * @retval None
+ */
+void EXTI_ClearITPendingBit(uint32_t EXTI_Line)
+{
+ /* Check the parameters */
+ assert_param(IS_EXTI_LINE(EXTI_Line));
+
+ EXTI->PR = EXTI_Line;
+}
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_flash.c b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_flash.c
new file mode 100644
index 0000000..2c1aeeb
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_flash.c
@@ -0,0 +1,1081 @@
+/**
+ ******************************************************************************
+ * @file hk32f030m_flash.c
+ * @author Rakan.z/laura.C
+ * @version V1.0
+ * @brief API file of flash module
+ * @changelist
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "hk32f030m_flash.h"
+
+
+
+/* FLASH driver modules */
+/*
+ ===============================================================================
+ ##### FLASH Interface configuration functions #####
+ ===============================================================================
+
+ [..] FLASH_Interface configuration_Functions, includes the following functions:
+ (+) void FLASH_SetLatency(uint32_t FLASH_Latency):
+ [..] 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)
+ [..]
+ +--------------------------------------------- +
+ | Wait states | HCLK clock frequency (MHz) |
+ |---------------|------------------------------|
+ |0WS(1CPU cycle)| 0 < HCLK <= 24 |
+ |---------------|------------------------------|
+ |1WS(2CPU cycle)| 24 < HCLK <= 32 |
+ +----------------------------------------------+
+ [..]
+ (+) void FLASH_PrefetchBufferCmd(FunctionalState NewState);
+ [..]
+ All these functions don't need the unlock sequence.
+
+*/
+
+/**
+ * @brief Sets the code latency value.
+ * @param FLASH_Latency: specifies the FLASH Latency value.
+ * This parameter can be one of the following values:
+ * @arg FLASH_Latency_0: FLASH Zero Latency cycle
+ * @arg FLASH_Latency_1: FLASH One Latency cycle
+ * @arg FLASH_Latency_2: FLASH two Latency cycle
+ * @arg FLASH_Latency_3: FLASH three Latency cycle
+ * @retval None
+ */
+void FLASH_SetLatency(uint32_t FLASH_Latency)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_FLASH_LATENCY(FLASH_Latency));
+
+ /* Read the ACR register */
+ tmpreg = FLASH->ACR;
+
+ /* Sets the Latency value */
+ tmpreg &= (uint32_t) (~((uint32_t)FLASH_ACR_LATENCY));
+ tmpreg |= FLASH_Latency;
+
+ /* Write the ACR register */
+ FLASH->ACR = tmpreg;
+}
+
+
+/* FLASH Memory Programming functions
+ *
+ ===============================================================================
+ ##### FLASH Memory Programming functions #####
+ ===============================================================================
+
+ [..] The FLASH Memory Programming functions, includes the following functions:
+ (+) void FLASH_Unlock(void);
+ (+) void FLASH_Lock(void);
+ (+) FLASH_Status FLASH_ErasePage(uint32_t Page_Address);
+ (+) FLASH_Status FLASH_EraseAllPages(void);
+ (+) FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data);
+ (+) FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data);
+ (+) FLASH_Status FLASH_ProgramByte(uint32_t Address, uint8_t Data)
+
+ [..] Any operation of erase or program should follow these steps:
+
+ (#) Call the FLASH_Unlock() function to enable the flash control register and
+ program memory access
+ (#) Call the desired function to erase page or program data
+ (#) Call the FLASH_Lock() to disable the flash program memory access
+ (recommended to protect the FLASH memory against possible unwanted operation)
+ */
+
+/**
+ * @brief Unlocks the FLASH control register and program memory access.
+ * @param None
+ * @retval None
+ */
+void FLASH_Unlock(void)
+{
+ if((FLASH->CR & FLASH_CR_LOCK) != RESET)
+ {
+ /* Unlocking the program memory access */
+ FLASH->KEYR = FLASH_FKEY1;
+ FLASH->KEYR = FLASH_FKEY2;
+ }
+}
+
+/**
+ * @brief Locks the Program memory access.
+ * @param None
+ * @retval None
+ */
+void FLASH_Lock(void)
+{
+ /* Set the LOCK Bit to lock the FLASH control register and program memory access */
+ FLASH->CR |= FLASH_CR_LOCK;
+}
+
+/**
+ * @brief Erases a specified page in program memory.
+ * @note To correctly run this function, the FLASH_Unlock() function must be called before.
+ * @note Call the FLASH_Lock() to disable the flash memory access (recommended
+ * to protect the FLASH memory against possible unwanted operation)
+ * @param Page_Address: The page address in program memory to be erased.
+ * @note A Page is erased in the Program memory only if the address to load
+ * is the start address of a page (multiple of 128 bytes).
+ * @retval FLASH Status: The returned value can be:
+ * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+ */
+FLASH_Status FLASH_ErasePage(uint32_t Page_Address)
+{
+ FLASH_Status status = FLASH_COMPLETE;
+
+ /* Check the parameters */
+ assert_param(IS_FLASH_PROGRAM_ADDRESS(Page_Address));
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+
+ if(status == FLASH_COMPLETE)
+ {
+ /* If the previous operation is completed, proceed to erase the page */
+ FLASH->CR |= FLASH_CR_PER;
+ FLASH->AR = Page_Address;
+ FLASH->CR |= FLASH_CR_STRT;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+
+ /* Disable the PER Bit */
+ FLASH->CR &= ~FLASH_CR_PER;
+ }
+
+ /* Return the Erase Status */
+ return status;
+}
+
+/**
+ * @brief Erases all FLASH pages.
+ * @note To correctly run this function, the FLASH_Unlock() function must be called before.
+ * @note Call the FLASH_Lock() to disable the flash memory access (recommended
+ * to protect the FLASH memory against possible unwanted operation)
+ * @param None
+ * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
+ * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+ */
+FLASH_Status FLASH_EraseAllPages(void)
+{
+ FLASH_Status status = FLASH_COMPLETE;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+
+ if(status == FLASH_COMPLETE)
+ {
+ /* if the previous operation is completed, proceed to erase all pages */
+ FLASH->CR |= FLASH_CR_MER;
+ FLASH->CR |= FLASH_CR_STRT;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+
+ /* Disable the MER Bit */
+ FLASH->CR &= ~FLASH_CR_MER;
+ }
+
+ /* Return the Erase Status */
+ return status;
+}
+
+
+/**
+ * @brief Programs a half word at a specified address.
+ * @note To correctly run this function, the FLASH_Unlock() function must be called before.
+ * @note Call the FLASH_Lock() to disable the flash memory access (recommended
+ * to protect the FLASH memory against possible unwanted operation)
+ * @param Address: specifies the address to be programmed.
+ * @param Data: specifies the data to be programmed.
+ * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
+ * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+ */
+FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data)
+{
+ FLASH_Status status = FLASH_COMPLETE;
+
+ /* Check the parameters */
+ assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+
+ if(status == FLASH_COMPLETE)
+ {
+ /* If the previous operation is completed, proceed to program the new data */
+ FLASH->CR |= FLASH_CR_PG;
+
+ *(__IO uint16_t*)Address = Data;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+
+ /* Disable the PG Bit */
+ FLASH->CR &= ~FLASH_CR_PG;
+ }
+
+ /* Return the Program Status */
+ return status;
+}
+
+/**
+ * @brief Programs a byte at a specified address.
+ * @note To correctly run this function, the FLASH_Unlock() function must be called before.
+ * @note Call the FLASH_Lock() to disable the flash memory access (recommended
+ * to protect the FLASH memory against possible unwanted operation)
+ * @param Address: specifies the address to be programmed.
+ * @param Data: specifies the data to be programmed.
+ * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
+ * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+ */
+FLASH_Status FLASH_ProgramByte(uint32_t Address, uint8_t Data)
+{
+ FLASH_Status status = FLASH_COMPLETE;
+
+ /* Check the parameters */
+ assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+
+ if(status == FLASH_COMPLETE)
+ {
+ /* If the previous operation is completed, proceed to program the new data */
+ FLASH->ECR |= FLASH_ECR_BPG;
+
+ *(__IO uint8_t*)Address = Data;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+
+ /* Disable the PG Bit */
+ FLASH->ECR &= ~FLASH_ECR_BPG;
+ }
+
+ /* Return the Program Status */
+ return status;
+}
+
+/**
+ * @brief Unlocks the option bytes block access.
+ * @param None
+ * @retval None
+ */
+void FLASH_OB_Unlock(void)
+{
+ if((FLASH->CR & FLASH_CR_OPTWRE) == RESET)
+ {
+ /* Unlocking the option bytes block access */
+ FLASH->OPTKEYR = FLASH_OPTKEY1;
+ FLASH->OPTKEYR = FLASH_OPTKEY2;
+ }
+}
+
+/**
+ * @brief Locks the option bytes block access.
+ * @param None
+ * @retval None
+ */
+void FLASH_OB_Lock(void)
+{
+ /* Set the OPTWREN Bit to lock the option bytes block access */
+ FLASH->CR &= ~FLASH_CR_OPTWRE;
+}
+
+
+/**
+ * @brief Erases the FLASH option bytes.
+ * @note To correctly run this function, the FLASH_OB_Unlock() function must be called before.
+ * @note Call the FLASH_OB_Lock() to disable the flash control register access and the option
+ * bytes (recommended to protect the FLASH memory against possible unwanted operation)
+ * @note This functions erases all option bytes except the Read protection (RDP).
+ * @param None
+ * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
+ * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+ */
+FLASH_Status FLASH_OB_EraseByte(uint32_t Address)
+{
+ FLASH_Status status = FLASH_COMPLETE;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+
+ if(status == FLASH_COMPLETE)
+ {
+ FLASH->CR |= FLASH_CR_OPTER;
+ FLASH->AR = Address;
+ FLASH->CR |= FLASH_CR_STRT;
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+ }
+ /* If the erase operation is completed, disable the OPTER Bit */
+ FLASH->CR &= ~FLASH_CR_OPTER;
+ return status;
+}
+
+/**
+ * @brief Write protects the desired pages
+ * @note To correctly run this function, the FLASH_OB_Unlock() function must be called before.
+ * @note Call the FLASH_OB_Lock() to disable the flash control register access and the option
+ * bytes (recommended to protect the FLASH memory against possible unwanted operation)
+ * @param OB_WRP: specifies the address of the pages to be write protected.
+ * This parameter can be:
+ * @arg OB_WRP_Pages0to3..OB_WRP_Pages124to127
+ * @arg OB_WRP_AllPages
+ * @arg OB_WRP_None
+ * @retval FLASH Status: The returned value can be:
+ * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+ */
+FLASH_Status FLASH_OB_WRPConfig(uint32_t OB_WRP)
+{
+ uint16_t WRP0_Data = 0xFFFF, WRP1_Data = 0xFFFF, WRP2_Data = 0xFFFF, WRP3_Data = 0xFFFF;
+ uint32_t WRP_ADDR = FLASH_OB_WRP_ADDRESS;
+ uint16_t i=0;
+
+ FLASH_Status status = FLASH_COMPLETE;
+
+ OB_WRP = (uint32_t)(~OB_WRP);
+ WRP0_Data = (uint16_t)(OB_WRP & OB_WRP0_WRP0);
+ WRP1_Data = (uint16_t)((OB_WRP >> 8) & OB_WRP0_WRP0);
+ WRP2_Data = (uint16_t)((OB_WRP >> 16) & OB_WRP0_WRP0) ;
+ WRP3_Data = (uint16_t)((OB_WRP >> 24) & OB_WRP0_WRP0) ;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+
+ for(i=0; i<8; i++)
+ {
+ if(status == FLASH_COMPLETE)
+ {
+ FLASH->CR |= FLASH_CR_OPTER;
+ FLASH->AR = WRP_ADDR;
+ FLASH->CR |= FLASH_CR_STRT;
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+
+ }
+ WRP_ADDR++;
+ }
+ if(status == FLASH_COMPLETE)
+ {
+
+ /* If the erase operation is completed, disable the OPTER Bit */
+ FLASH->CR &= ~FLASH_CR_OPTER;
+
+ FLASH->CR |= FLASH_CR_OPTPG;
+
+ if(WRP0_Data != 0xFF)
+ {
+ OB->WRP0 = WRP0_Data;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+ }
+ if((status == FLASH_COMPLETE) && (WRP1_Data != 0xFF))
+ {
+ OB->WRP1 = WRP1_Data;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+ }
+ if((status == FLASH_COMPLETE) && (WRP2_Data != 0xFF))
+ {
+ OB->WRP2 = WRP2_Data;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+ }
+ if((status == FLASH_COMPLETE) && (WRP3_Data != 0xFF))
+ {
+ OB->WRP3 = WRP3_Data;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+ }
+ if(status != FLASH_TIMEOUT)
+ {
+ /* if the program operation is completed, disable the OPTPG Bit */
+ FLASH->CR &= ~FLASH_CR_OPTPG;
+ }
+ }
+ /* Return the write protection operation Status */
+ return status;
+}
+
+/**
+ * @brief Enables or disables the read out protection.
+ * @note To correctly run this function, the FLASH_OB_Unlock() function must be called before.
+ * @note Call the FLASH_OB_Lock() to disable the flash control register access and the option
+ * bytes (recommended to protect the FLASH memory against possible unwanted operation)
+ * @param FLASH_ReadProtection_Level: specifies the read protection level.
+ * This parameter can be:
+ * @arg OB_RDP_Level_0: No protection
+ * @arg OB_RDP_Level_1: Read protection of the memory
+ * @arg OB_RDP_Level_2: Chip protection
+ * @note When enabling OB_RDP level 2 it's no more possible to go back to level 1 or 0
+ * @retval FLASH Status: The returned value can be:
+ * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+ */
+FLASH_Status FLASH_OB_RDPConfig(uint8_t OB_RDP)
+{
+ FLASH_Status status = FLASH_COMPLETE;
+ uint32_t WRP_ADDR = FLASH_OB_RDP_ADDRESS;
+ /* Check the parameters */
+ assert_param(IS_OB_RDP(OB_RDP));
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+
+ if(status == FLASH_COMPLETE)
+ {
+ if(status == FLASH_COMPLETE)
+ {
+ FLASH->CR |= FLASH_CR_OPTER;
+ FLASH->AR = WRP_ADDR;
+ FLASH->CR |= FLASH_CR_STRT;
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+ }
+ if(status == FLASH_COMPLETE)
+ {
+ FLASH->CR |= FLASH_CR_OPTER;
+ FLASH->AR = WRP_ADDR+1;
+ FLASH->CR |= FLASH_CR_STRT;
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+ }
+
+ if(status == FLASH_COMPLETE)
+ {
+ /* If the erase operation is completed, disable the OPTER Bit */
+ FLASH->CR &= ~FLASH_CR_OPTER;
+
+ /* Enable the Option Bytes Programming operation */
+ FLASH->CR |= FLASH_CR_OPTPG;
+
+ OB->RDP = OB_RDP;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+
+ if(status != FLASH_TIMEOUT)
+ {
+ /* if the program operation is completed, disable the OPTPG Bit */
+ FLASH->CR &= ~FLASH_CR_OPTPG;
+ }
+ }
+ else
+ {
+ if(status != FLASH_TIMEOUT)
+ {
+ /* Disable the OPTER Bit */
+ FLASH->CR &= ~FLASH_CR_OPTER;
+ }
+ }
+ }
+ /* Return the protection operation Status */
+ return status;
+}
+
+/**
+ * @brief Programs the FLASH User Option Byte: IWDG_SW / RST_STOP.
+ * @note To correctly run this function, the FLASH_OB_Unlock() function must be called before.
+ * @note Call the FLASH_OB_Lock() to disable the flash control register access and the option
+ * bytes (recommended to protect the FLASH memory against possible unwanted operation)
+ * @param OB_IWDG: Selects the WDG mode
+ * This parameter can be one of the following values:
+ * @arg OB_IWDG_SW: Software WDG selected
+ * @arg OB_IWDG_HW: Hardware WDG selected
+ * @param OB_STOP: Reset event when entering STOP mode.
+ * This parameter can be one of the following values:
+ * @arg OB_STOP_NoRST: No reset generated when entering in STOP
+ * @arg OB_STOP_RST: Reset generated when entering in STOP
+ * @retval FLASH Status: The returned value can be:
+ * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+ */
+FLASH_Status FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP)
+{
+ FLASH_Status status = FLASH_COMPLETE;
+ uint32_t WRP_ADDR = FLASH_OB_USER_ADDRESS;
+
+ /* Check the parameters */
+ assert_param(IS_OB_IWDG_SOURCE(OB_IWDG));
+ assert_param(IS_OB_STOP_SOURCE(OB_STOP));
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+
+ if(status == FLASH_COMPLETE)
+ {
+ FLASH->CR |= FLASH_CR_OPTER;
+ FLASH->AR = WRP_ADDR;
+ FLASH->CR |= FLASH_CR_STRT;
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+ }
+ if(status == FLASH_COMPLETE)
+ {
+ FLASH->CR |= FLASH_CR_OPTER;
+ FLASH->AR = WRP_ADDR+1;
+ FLASH->CR |= FLASH_CR_STRT;
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+ }
+
+ if(status == FLASH_COMPLETE)
+ {
+ /*clear the CR_OPTER bit*/
+ FLASH->CR &= ~FLASH_CR_OPTER;
+ /* Enable the Option Bytes Programming operation */
+ FLASH->CR |= FLASH_CR_OPTPG;
+
+ OB->USER = (uint16_t)((uint16_t)(OB_IWDG | OB_STOP));
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+
+ if(status != FLASH_TIMEOUT)
+ {
+ /* If the program operation is completed, disable the OPTPG Bit */
+ FLASH->CR &= ~FLASH_CR_OPTPG;
+ }
+ }
+ else
+ {
+ if(status != FLASH_TIMEOUT)
+ {
+ /* Disable the OPTER Bit */
+ FLASH->CR &= ~FLASH_CR_OPTER;
+ }
+ }
+ /* Return the Option Byte program Status */
+ return status;
+}
+
+/**
+ * @brief Programs the FLASH User Option Byte: IWDG_RL_IV
+ * @note To correctly run this function, the FLASH_OB_Unlock() function must be called before.
+ * @note Call the FLASH_OB_Lock() to disable the flash control register access and the option
+ * bytes (recommended to protect the FLASH memory against possible unwanted operation)
+ * @param
+ * @retval FLASH Status: The returned value can be:
+ * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+ */
+FLASH_Status FLASH_OB_IWDG_RLRConfig(uint16_t OB_IWDG_RLR, FunctionalState NewState)
+{
+ FLASH_Status status = FLASH_COMPLETE;
+ uint32_t WRP_ADDR = FLASH_OB_IWDG_ADDRESS;
+ uint16_t i=0;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+
+ for(i=0; i<4; i++)
+ {
+ if(status == FLASH_COMPLETE)
+ {
+ FLASH->CR |= FLASH_CR_OPTER;
+ FLASH->AR = WRP_ADDR;
+ FLASH->CR |= FLASH_CR_STRT;
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+
+ }
+ WRP_ADDR++;
+ }
+ /* If the erase operation is completed, disable the OPTER Bit */
+ FLASH->CR &= ~FLASH_CR_OPTER;
+
+ if(NewState == ENABLE)
+ {
+ if(status == FLASH_COMPLETE)
+ {
+ FLASH->CR |= FLASH_CR_OPTPG;
+ OB->IWDG_RL_IV = (uint16_t)(OB_IWDG_RLR);
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+ }
+ if(status == FLASH_COMPLETE)
+ {
+ FLASH->CR |= FLASH_CR_OPTPG;
+ OB->IWDG_INI_KEY = (uint16_t)(0x5b1e);
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+ }
+
+ if(status != FLASH_TIMEOUT)
+ {
+ /* If the program operation is completed, disable the OPTPG Bit */
+ FLASH->CR &= ~FLASH_CR_OPTPG;
+ }
+ }
+ /* Return the Option Byte program Status */
+ return status;
+}
+
+
+/**
+ * @brief Programs the FLASH User Option Byte: LSI_LP_CTL
+ * @note To correctly run this function, the FLASH_OB_Unlock() function must be called before.
+ * @note Call the FLASH_OB_Lock() to disable the flash control register access and the option
+ * bytes (recommended to protect the FLASH memory against possible unwanted operation)
+ * @param
+ * @retval FLASH Status: The returned value can be:
+ * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+ */
+FLASH_Status FLASH_OB_LSILPConfig(FunctionalState NewState)
+{
+ FLASH_Status status = FLASH_COMPLETE;
+ uint32_t WRP_ADDR = FLASH_OB_LSI_LP_ADDRESS;
+ uint16_t i=0;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+
+ for(i=0; i<2; i++)
+ {
+ if(status == FLASH_COMPLETE)
+ {
+ FLASH->CR |= FLASH_CR_OPTER;
+ FLASH->AR = WRP_ADDR;
+ FLASH->CR |= FLASH_CR_STRT;
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+
+
+ }
+ WRP_ADDR++;
+ }
+ /* If the erase operation is completed, disable the OPTER Bit */
+ FLASH->CR &= ~FLASH_CR_OPTER;
+ if(NewState == ENABLE)
+ {
+ if(status == FLASH_COMPLETE)
+ {
+ FLASH->CR |= FLASH_CR_OPTPG;
+ OB->LSI_LP_CTL = (uint16_t)(0x369C);
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+ }
+
+ if(status != FLASH_TIMEOUT)
+ {
+ /* If the program operation is completed, disable the OPTPG Bit */
+ FLASH->CR &= ~FLASH_CR_OPTPG;
+ }
+ }
+ /* Return the Option Byte program Status */
+ return status;
+}
+
+/**
+ * @brief Programs the FLASH User Option Byte: DBG_CLK_CTL
+ * @note To correctly run this function, the FLASH_OB_Unlock() function must be called before.
+ * @note Call the FLASH_OB_Lock() to disable the flash control register access and the option
+ * bytes (recommended to protect the FLASH memory against possible unwanted operation)
+ * @param
+ * @retval FLASH Status: The returned value can be:
+ * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+ */
+FLASH_Status FLASH_OB_DBGCLKConfig(FunctionalState NewState)
+{
+ FLASH_Status status = FLASH_COMPLETE;
+ uint32_t WRP_ADDR = FLASH_OB_DBG_CLK_ADDRESS;
+ uint16_t i=0;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+
+ for(i=0; i<2; i++)
+ {
+ if(status == FLASH_COMPLETE)
+ {
+ FLASH->CR |= FLASH_CR_OPTER;
+ FLASH->AR = WRP_ADDR;
+ FLASH->CR |= FLASH_CR_STRT;
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+
+
+ }
+ WRP_ADDR++;
+ }
+ /* If the erase operation is completed, disable the OPTER Bit */
+ FLASH->CR &= ~FLASH_CR_OPTER;
+ if(NewState == ENABLE)
+ {
+ if(status == FLASH_COMPLETE)
+ {
+ FLASH->CR |= FLASH_CR_OPTPG;
+ OB->DBG_CLK_CTL = (uint16_t)(0x12de);
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+ }
+
+ if(status != FLASH_TIMEOUT)
+ {
+ /* If the program operation is completed, disable the OPTPG Bit */
+ FLASH->CR &= ~FLASH_CR_OPTPG;
+ }
+ }
+ /* Return the Option Byte program Status */
+ return status;
+}
+
+
+/**
+ * @brief Programs the FLASH User Option Byte: IWDG_SW, RST_STOP
+ * VDDA ANALOG monitoring.
+ * @note To correctly run this function, the FLASH_OB_Unlock() function must be called before.
+ * @note Call the FLASH_OB_Lock() to disable the flash control register access and the option
+ * bytes (recommended to protect the FLASH memory against possible unwanted operation)
+ * @param OB_USER: Selects all user option bytes
+ * This parameter is a combination of the following values:
+ * @arg OB_IWDG_SW / OB_IWDG_HW: Software / Hardware WDG selected
+ * @arg OB_STOP_NoRST / OB_STOP_RST: No reset / Reset generated when entering in STOP
+ * @retval FLASH Status: The returned value can be:
+ * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+ */
+FLASH_Status FLASH_OB_WriteUser(uint8_t OB_USER)
+{
+ FLASH_Status status = FLASH_COMPLETE;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+
+ if(status == FLASH_COMPLETE)
+ {
+ /* Enable the Option Bytes Programming operation */
+ FLASH->CR |= FLASH_CR_OPTPG;
+
+ OB->USER = OB_USER;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+
+ if(status != FLASH_TIMEOUT)
+ {
+ /* If the program operation is completed, disable the OPTPG Bit */
+ FLASH->CR &= ~FLASH_CR_OPTPG;
+ }
+ }
+ /* Return the Option Byte program Status */
+ return status;
+
+}
+
+/**
+ * @brief Programs a half word at a specified Option Byte Data address.
+ * @note To correctly run this function, the FLASH_OB_Unlock() function must be called before.
+ * @note Call the FLASH_OB_Lock() to disable the flash control register access and the option
+ * bytes (recommended to protect the FLASH memory against possible unwanted operation)
+ * @param Address: specifies the address to be programmed.
+ * This parameter can be 0x1FFFF804 or 0x1FFFF806.
+ * @param Data: specifies the data to be programmed.
+ * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
+ * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+ */
+FLASH_Status FLASH_OB_ProgramData(uint32_t Address, uint16_t Data)
+{
+ FLASH_Status status = FLASH_COMPLETE;
+ /* Check the parameters */
+ assert_param(IS_OB_DATA_ADDRESS(Address));
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+
+ if(status == FLASH_COMPLETE)
+ {
+ /* Enables the Option Bytes Programming operation */
+ FLASH->CR |= FLASH_CR_OPTPG;
+ *(__IO uint16_t*)Address = Data;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+
+ if(status != FLASH_TIMEOUT)
+ {
+ /* If the program operation is completed, disable the OPTPG Bit */
+ FLASH->CR &= ~FLASH_CR_OPTPG;
+ }
+ }
+ /* Return the Option Byte Data Program Status */
+ return status;
+}
+
+/**
+ * @brief Returns the FLASH User Option Bytes values.
+ * @param None
+ * @retval The FLASH User Option Bytes .
+ */
+uint8_t FLASH_OB_GetUser(void)
+{
+ /* Return the User Option Byte */
+ return (uint8_t)(FLASH->OBR >> 8);
+}
+
+/**
+ * @brief Returns the FLASH Write Protection Option Bytes value.
+ * @param None
+ * @retval The FLASH Write Protection Option Bytes value
+ */
+uint32_t FLASH_OB_GetWRP(void)
+{
+ /* Return the FLASH write protection Register value */
+ return (uint32_t)(FLASH->WRPR);
+}
+
+/**
+ * @brief Checks whether the FLASH Read out Protection Status is set or not.
+ * @param None
+ * @retval FLASH ReadOut Protection Status(SET or RESET)
+ */
+FlagStatus FLASH_OB_GetRDP(void)
+{
+ FlagStatus readstatus = RESET;
+
+ if ((uint8_t)(FLASH->OBR & (FLASH_OBR_RDPRT1 | FLASH_OBR_RDPRT2)) != RESET)
+ {
+ readstatus = SET;
+ }
+ else
+ {
+ readstatus = RESET;
+ }
+ return readstatus;
+}
+
+
+/** FLASH_Group4 Interrupts and flags management functions
+ * Interrupts and flags management functions
+ *
+
+ ===============================================================================
+ ##### Interrupts and flags management functions #####
+ ===============================================================================
+ */
+
+/**
+ * @brief Enables or disables the specified FLASH interrupts.
+ * @param FLASH_IT: specifies the FLASH interrupt sources to be enabled or
+ * disabled.
+ * This parameter can be any combination of the following values:
+ * @arg FLASH_IT_EOP: FLASH end of programming Interrupt
+ * @arg FLASH_IT_ERR: FLASH Error Interrupt
+ * @retval None
+ */
+void FLASH_ITConfig(uint32_t FLASH_IT, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FLASH_IT(FLASH_IT));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if(NewState != DISABLE)
+ {
+ /* Enable the interrupt sources */
+ FLASH->CR |= FLASH_IT;
+ }
+ else
+ {
+ /* Disable the interrupt sources */
+ FLASH->CR &= ~(uint32_t)FLASH_IT;
+ }
+}
+
+/**
+ * @brief Checks whether the specified FLASH flag is set or not.
+ * @param FLASH_FLAG: specifies the FLASH flag to check.
+ * This parameter can be one of the following values:
+ * @arg FLASH_FLAG_BSY: FLASH write/erase operations in progress flag
+ * @arg FLASH_FLAG_WRPERR: FLASH Write protected error flag
+ * @arg FLASH_FLAG_EOP: FLASH End of Programming flag
+ * @retval The new state of FLASH_FLAG (SET or RESET).
+ */
+FlagStatus FLASH_GetFlagStatus(uint32_t FLASH_FLAG)
+{
+ FlagStatus bitstatus = RESET;
+
+ /* Check the parameters */
+ assert_param(IS_FLASH_GET_FLAG(FLASH_FLAG));
+
+ if((FLASH->SR & FLASH_FLAG) != (uint32_t)RESET)
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+ /* Return the new state of FLASH_FLAG (SET or RESET) */
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the FLASH's pending flags.
+ * @param FLASH_FLAG: specifies the FLASH flags to clear.
+ * This parameter can be any combination of the following values:
+ * @arg FLASH_FLAG_WRPERR: FLASH Write protected error flag
+ * @arg FLASH_FLAG_EOP: FLASH End of Programming flag
+ * @retval None
+ */
+void FLASH_ClearFlag(uint32_t FLASH_FLAG)
+{
+ /* Check the parameters */
+ assert_param(IS_FLASH_CLEAR_FLAG(FLASH_FLAG));
+
+ /* Clear the flags */
+ FLASH->SR = FLASH_FLAG;
+}
+
+/**
+ * @brief Returns the FLASH Status.
+ * @param None
+ * @retval FLASH Status: The returned value can be:
+ * FLASH_BUSY, FLASH_ERROR_WRP or FLASH_COMPLETE.
+ */
+FLASH_Status FLASH_GetStatus(void)
+{
+ FLASH_Status FLASHstatus = FLASH_COMPLETE;
+
+ if((FLASH->SR & FLASH_FLAG_BSY) == FLASH_FLAG_BSY)
+ {
+ FLASHstatus = FLASH_BUSY;
+ }
+ else
+ {
+ if((FLASH->SR & (uint32_t)FLASH_FLAG_WRPERR)!= (uint32_t)0x00)
+ {
+ FLASHstatus = FLASH_ERROR_WRP;
+ }
+ else
+ {
+ FLASHstatus = FLASH_COMPLETE;
+ }
+ }
+ /* Return the FLASH Status */
+ return FLASHstatus;
+}
+
+
+/**
+ * @brief Waits for a FLASH operation to complete or a TIMEOUT to occur.
+ * @param Timeout: FLASH programming Timeout
+ * @retval FLASH Status: The returned value can be: FLASH_BUSY,
+ * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+ */
+FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout)
+{
+ FLASH_Status status = FLASH_COMPLETE;
+
+ /* Check for the FLASH Status */
+ status = FLASH_GetStatus();
+
+ /* Wait for a FLASH operation to complete or a TIMEOUT to occur */
+ while((status == FLASH_BUSY) && (Timeout != 0x00))
+ {
+ status = FLASH_GetStatus();
+ Timeout--;
+ }
+
+ if(Timeout == 0x00 )
+ {
+ status = FLASH_TIMEOUT;
+ }
+ /* Return the operation status */
+ return status;
+}
+
+
+/**
+ * @brief erase a byte at a EEPROM address.
+ * @param Address: specifies the address to be programmed.
+ * @param Data: specifies the data to be programmed.
+ * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
+ * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+ */
+FLASH_Status EEPROM_EraseByte(uint32_t Address)
+{
+ FLASH_Status status = FLASH_COMPLETE;
+
+ /* Check the parameters */
+ assert_param(IS_EEPROM_PROGRAM_ADDRESS(Address));
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+
+ if(status == FLASH_COMPLETE)
+ {
+ /* If the previous operation is completed, proceed to program the new data */
+ FLASH->ECR |= FLASH_ECR_EEPROM_ER;
+ FLASH->AR = Address;
+ FLASH->CR |= FLASH_CR_STRT;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+
+ /* Disable the PG Bit */
+ FLASH->ECR &= ~FLASH_ECR_EEPROM_ER;
+ }
+
+ /* Return the Program Status */
+ return status;
+}
+
+
+/**
+ * @brief Programs a byte at a EEPROM address.
+ * @param Address: specifies the address to be programmed.
+ * @param Data: specifies the data to be programmed.
+ * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
+ * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+ */
+FLASH_Status EEPROM_ProgramByte(uint32_t Address, uint8_t Data)
+{
+ FLASH_Status status = FLASH_COMPLETE;
+
+ /* Check the parameters */
+ assert_param(IS_EEPROM_PROGRAM_ADDRESS(Address));
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+
+ if(status == FLASH_COMPLETE)
+ {
+ /* If the previous operation is completed, proceed to program the new data */
+ FLASH->ECR |= FLASH_ECR_EEPROM_BPG;
+
+ *(__IO uint8_t*)Address = Data;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
+
+ /* Disable the PG Bit */
+ FLASH->ECR &= ~FLASH_ECR_EEPROM_BPG;
+ }
+
+ /* Return the Program Status */
+ return status;
+}
+
+/**
+ * @brief Return the unique device identifier (UID based on 64 bits)
+ * @param UID: pointer to 2 words array.
+ * @retval Device identifier
+ */
+void Sys_GetDevice64BitUID(uint32_t *UID)
+{
+ UID[0] = (uint32_t)(READ_REG(*((uint32_t *)UID_BASE)));
+ UID[1] = (uint32_t)(READ_REG(*((uint32_t *)(UID_BASE + 4U))));
+}
+
+
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_gpio.c b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_gpio.c
new file mode 100644
index 0000000..ba1148c
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_gpio.c
@@ -0,0 +1,700 @@
+/**
+ ******************************************************************************
+ * @file hk32f030m_gpio.c
+ * @author Rakan.z
+ * @version V1.0
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "hk32f030m_gpio.h"
+#include "hk32f030m_rcc.h"
+
+/** @defgroup GPIO
+ * @brief GPIO driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup GPIO_Private_Functions
+ * @{
+ */
+
+/** @defgroup GPIO_Group1 Initialization and Configuration
+ * @brief Initialization and Configuration
+ *
+@verbatim
+ ===============================================================================
+ ##### Initialization and Configuration #####
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Deinitializes the GPIOx peripheral registers to their default reset
+ * values.
+ * @param GPIOx: where x can be (A, B, C, D) to select the GPIO peripheral.
+ * @retval None
+ */
+void GPIO_DeInit(GPIO_TypeDef* GPIOx)
+{
+ /* Check the parameters */
+ assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
+
+ if(GPIOx == GPIOA)
+ {
+ RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOA, ENABLE);
+ RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOA, DISABLE);
+ }
+ else if(GPIOx == GPIOB)
+ {
+ RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOB, ENABLE);
+ RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOB, DISABLE);
+ }
+ else if(GPIOx == GPIOC)
+ {
+ RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOC, ENABLE);
+ RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOC, DISABLE);
+ }
+ else
+ {
+ if(GPIOx == GPIOD)
+ {
+ RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOD, ENABLE);
+ RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOD, DISABLE);
+ }
+ }
+}
+
+/**
+ * @brief Initializes the GPIOx peripheral according to the specified
+ * parameters in the GPIO_InitStruct.
+ * @param GPIOx: where x can be (A, B, C, D) to select the GPIO peripheral.
+ * @param GPIO_InitStruct: pointer to a GPIO_InitTypeDef structure that contains
+ * the configuration information for the specified GPIO peripheral.
+ * @retval None
+ */
+void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
+{
+ uint32_t pinpos = 0x00, pos = 0x00 , currentpin = 0x00;
+
+ /* Check the parameters */
+ assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
+ assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin));
+ assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode));
+ assert_param(IS_GPIO_PUPD(GPIO_InitStruct->GPIO_PuPd));
+
+ /*-------------------------- Configure the port pins -----------------------*/
+ /*-- GPIO Mode Configuration --*/
+ for (pinpos = 0x00; pinpos < 0x10; pinpos++)
+ {
+ pos = ((uint32_t)0x01) << pinpos;
+
+ /* Get the port pins position */
+ currentpin = (GPIO_InitStruct->GPIO_Pin) & pos;
+
+ if (currentpin == pos)
+ {
+ if ((GPIO_InitStruct->GPIO_Mode == GPIO_Mode_OUT) || (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_AF))
+ {
+ /* Check Speed mode parameters */
+ assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed));
+
+ /* Speed mode configuration */
+ GPIOx->OSPEEDR &= ~(GPIO_OSPEEDR_OSPEEDR0 << (pinpos * 2));
+ GPIOx->OSPEEDR |= ((uint32_t)(GPIO_InitStruct->GPIO_Speed) << (pinpos * 2));
+
+ /* Check Output mode parameters */
+ assert_param(IS_GPIO_OTYPE(GPIO_InitStruct->GPIO_OType));
+
+ /* Output mode configuration */
+ GPIOx->OTYPER &= ~((GPIO_OTYPER_OT_0) << ((uint16_t)pinpos));
+ GPIOx->OTYPER |= (uint16_t)(((uint16_t)GPIO_InitStruct->GPIO_OType) << ((uint16_t)pinpos));
+ }
+
+ GPIOx->MODER &= ~(GPIO_MODER_MODER0 << (pinpos * 2));
+
+ GPIOx->MODER |= (((uint32_t)GPIO_InitStruct->GPIO_Mode) << (pinpos * 2));
+
+ /* Pull-up Pull down resistor configuration */
+ GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << ((uint16_t)pinpos * 2));
+ GPIOx->PUPDR |= (((uint32_t)GPIO_InitStruct->GPIO_PuPd) << (pinpos * 2));
+ }
+ }
+
+ /* config schmit*/
+ if (GPIO_InitStruct->GPIO_Schmit == GPIO_Schmit_Disable)
+ {
+ GPIOx->IOSR |= (GPIO_InitStruct->GPIO_Pin);
+ }
+ else
+ {
+ GPIOx->IOSR &= ~(GPIO_InitStruct->GPIO_Pin);
+ }
+
+}
+
+/**
+ * @brief Fills each GPIO_InitStruct member with its default value.
+ * @param GPIO_InitStruct: pointer to a GPIO_InitTypeDef structure which will
+ * be initialized.
+ * @retval None
+ */
+void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct)
+{
+ /* Reset GPIO init structure parameters values */
+ GPIO_InitStruct->GPIO_Pin = GPIO_Pin_All;
+ GPIO_InitStruct->GPIO_Mode = GPIO_Mode_IN;
+ GPIO_InitStruct->GPIO_Speed = GPIO_Speed_Level_2;
+ GPIO_InitStruct->GPIO_OType = GPIO_OType_PP;
+ GPIO_InitStruct->GPIO_PuPd = GPIO_PuPd_NOPULL;
+}
+
+/**
+ * @brief Locks GPIO Pins configuration registers.
+ * @note The locked registers are GPIOx_MODER, GPIOx_OTYPER, GPIOx_OSPEEDR,
+ * GPIOx_PUPDR, GPIOx_AFRL and GPIOx_AFRH.
+ * @note The configuration of the locked GPIO pins can no longer be modified
+ * until the next device reset.
+ * @param GPIOx: where x can be (A or B) to select the GPIO peripheral.
+ * @param GPIO_Pin: specifies the port bit to be written.
+ * This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
+ * @retval None
+ */
+void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
+{
+ __IO uint32_t tmp = 0x00010000;
+
+ /* Check the parameters */
+ assert_param(IS_GPIO_LIST_PERIPH(GPIOx));
+ assert_param(IS_GPIO_PIN(GPIO_Pin));
+
+ tmp |= GPIO_Pin;
+ /* Set LCKK bit */
+ GPIOx->LCKR = tmp;
+ /* Reset LCKK bit */
+ GPIOx->LCKR = GPIO_Pin;
+ /* Set LCKK bit */
+ GPIOx->LCKR = tmp;
+ /* Read LCKK bit */
+ tmp = GPIOx->LCKR;
+ /* Read LCKK bit */
+ tmp = GPIOx->LCKR;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup GPIO_Group2 GPIO Read and Write
+ * @brief GPIO Read and Write
+ *
+@verbatim
+ ===============================================================================
+ ##### GPIO Read and Write #####
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Reads the specified input port pin bit.
+ * @param GPIOx: where x can be (A, B, C, D) to select the GPIO peripheral.
+ * @param GPIO_Pin: specifies the port bit to read.
+ * @note This parameter can be GPIO_Pin_x where x can be:
+ * (0..15) for GPIOA, GPIOB, GPIOC, for GPIOD
+ * @retval The input port pin value.
+ */
+uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
+{
+ uint8_t bitstatus = 0x00;
+
+ /* Check the parameters */
+ assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
+ assert_param(IS_GET_GPIO_PIN(GPIO_Pin));
+
+ if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)Bit_RESET)
+ {
+ bitstatus = (uint8_t)Bit_SET;
+ }
+ else
+ {
+ bitstatus = (uint8_t)Bit_RESET;
+ }
+ return bitstatus;
+}
+
+/**
+ * @brief Reads the specified input port pin.
+ * @param GPIOx: where x can be (A, B, C, D) to select the GPIO peripheral.
+ * @retval The input port pin value.
+ */
+uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx)
+{
+ /* Check the parameters */
+ assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
+
+ return ((uint16_t)GPIOx->IDR);
+}
+
+/**
+ * @brief Reads the specified output data port bit.
+ * @param GPIOx: where x can be (A, B, C, D) to select the GPIO peripheral.
+ * @param GPIO_Pin: Specifies the port bit to read.
+ * @note This parameter can be GPIO_Pin_x where x can be:
+ * (0..15) for GPIOA, GPIOB, GPIOC, for GPIOD
+ * @retval The output port pin value.
+ */
+uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
+{
+ uint8_t bitstatus = 0x00;
+
+ /* Check the parameters */
+ assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
+ assert_param(IS_GET_GPIO_PIN(GPIO_Pin));
+
+ if ((GPIOx->ODR & GPIO_Pin) != (uint32_t)Bit_RESET)
+ {
+ bitstatus = (uint8_t)Bit_SET;
+ }
+ else
+ {
+ bitstatus = (uint8_t)Bit_RESET;
+ }
+ return bitstatus;
+}
+
+/**
+ * @brief Reads the specified GPIO output data port.
+ * @param GPIOx: where x can be (A, B, C, D) to select the GPIO peripheral.
+
+ * @retval GPIO output data port value.
+ */
+uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx)
+{
+ /* Check the parameters */
+ assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
+
+ return ((uint16_t)GPIOx->ODR);
+}
+
+/**
+ * @brief Sets the selected data port bits.
+ * @param GPIOx: where x can be (A, B, C, D) to select the GPIO peripheral.
+ * @param GPIO_Pin: specifies the port bits to be written.
+ * @note This parameter can be GPIO_Pin_x where x can be:
+ * (0..15) for GPIOA, GPIOB, GPIOC, for GPIOD
+ * @retval None
+ */
+void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
+{
+ /* Check the parameters */
+ assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
+ assert_param(IS_GPIO_PIN(GPIO_Pin));
+
+ GPIOx->BSRR = GPIO_Pin;
+}
+
+/**
+ * @brief Clears the selected data port bits.
+ * @param GPIOx: where x can be (A, B, C, D) to select the GPIO peripheral.
+ * @param GPIO_Pin: specifies the port bits to be written.
+ * @note This parameter can be GPIO_Pin_x where x can be:
+ * (0..15) for GPIOA, GPIOB, GPIOC, for GPIOD
+ * @retval None
+ */
+void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
+{
+ /* Check the parameters */
+ assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
+ assert_param(IS_GPIO_PIN(GPIO_Pin));
+
+ GPIOx->BRR = GPIO_Pin;
+}
+
+/**
+ * @brief Writes the selected data port bit.
+ * @param GPIOx: where x can be (A, B, C, D) to select the GPIO peripheral.
+ * @param GPIO_Pin: specifies the port bit to be written.
+ * @param BitVal: specifies the value to be written to the selected bit.
+ * This parameter can be one of the BitAction enumeration values:
+ * @arg Bit_RESET: to clear the port pin
+ * @arg Bit_SET: to set the port pin
+ * @note This parameter can be GPIO_Pin_x where x can be:
+ * (0..15) for GPIOA, GPIOB, GPIOC, for GPIOD
+ * @retval None
+ */
+void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal)
+{
+ /* Check the parameters */
+ assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
+ assert_param(IS_GET_GPIO_PIN(GPIO_Pin));
+ assert_param(IS_GPIO_BIT_ACTION(BitVal));
+
+ if (BitVal != Bit_RESET)
+ {
+ GPIOx->BSRR = GPIO_Pin;
+ }
+ else
+ {
+ GPIOx->BRR = GPIO_Pin ;
+ }
+}
+
+/**
+ * @brief Writes data to the specified GPIO data port.
+ * @param GPIOx: where x can be (A, B, C, D) to select the GPIO peripheral.
+ * @param PortVal: specifies the value to be written to the port output data register.
+ * @retval None
+ */
+void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal)
+{
+ /* Check the parameters */
+ assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
+
+ GPIOx->ODR = PortVal;
+}
+
+/**
+ * @brief Toggle the GPIO port.
+ * @param GPIOx: where x can be (A, B, C, D) to select the GPIO peripheral.
+ * @param GPIO_Pin: sGPIO_pins_define
+ * GPIO_Pin_0
+ * GPIO_Pin_1
+ * GPIO_Pin_2
+ * GPIO_Pin_3
+ * GPIO_Pin_4
+ * GPIO_Pin_5
+ * GPIO_Pin_6
+ * GPIO_Pin_7
+ * GPIO_Pin_8
+ * GPIO_Pin_9
+ * GPIO_Pin_10
+ * GPIO_Pin_11
+ * GPIO_Pin_12
+ * GPIO_Pin_13
+ * GPIO_Pin_14
+ * GPIO_Pin_15
+ * @retval None
+ */
+void GPIO_Toggle(GPIO_TypeDef* GPIOx , uint16_t GPIO_Pin)
+{
+ GPIOx->ODR ^= GPIO_Pin;
+}
+
+/** @defgroup GPIO_Group3 GPIO Alternate functions configuration functions
+ * @brief GPIO Alternate functions configuration functions
+ *
+@verbatim
+ ===============================================================================
+ ##### GPIO Alternate functions configuration functions #####
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief selects the pin to used as Alternate function.
+ * @param GPIOx: where x can be (A, B, C, D) to select the GPIO peripheral.
+ * @param GPIO_PinSource: specifies the pin for the Alternate function.
+ * This parameter can be GPIO_PinSourcex where x can be (0..15) for GPIOA, GPIOB,GPIOB, GPIOD
+ * @param GPIO_AF: selects the pin to used as Alternate function.
+ * This parameter can be one of the following value:
+ * @arg GPIO_AF_0: (I2C1_WD)I2C1_SMBA, I2C1_SCL, SWCLK_I2C1_SDA, I2C1_SDA, SWDIO
+ * @arg GPIO_AF_1: (USART1)USART1_TX, USART1_RX, USART1_CK
+ * @arg GPIO_AF_2: (SPI)SPI1_SCK, SPI1_NSS, SPI1_MISO, SPI1_NSS, SPI1_MOSI
+ * @arg GPIO_AF_3: (TIM1)TIM1_BKIN, TIM1_CH1N, TIM1_CH2N, TIM1_CH3N,TIM1_CH3_CH1N,TIM1_CH4_CH2N, TIM1_ETR,TIM1_CH1,TIM1_CH2,TIM1_CH4,
+ * TIM1_ETR
+ * @arg GPIO_AF_4: (TIM2)TIM2_CH3, TIM2_ETR, TIM2_CH4, TIM2_CH2, TIM2_CH1
+ * @arg GPIO_AF_5: (RCC)RCC_MCO
+ * @arg GPIO_AF_6: (BEEPER)BEEP
+ * @arg GPIO_AF_7: (ADC1)ADC1_ETR
+ * @note The pin should already been configured in Alternate Function mode(AF)
+ * using GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AF
+ * @note Refer to the Alternate function mapping table in the device datasheet
+ * for the detailed mapping of the system and peripherals'alternate
+ * function I/O pins.
+ * @retval None
+ */
+
+void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF)
+{
+ uint32_t temp = 0x00;
+ uint32_t temp_2 = 0x00;
+
+ /* Check the parameters */
+ assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
+ assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource));
+ assert_param(IS_GPIO_AF(GPIO_AF));
+
+ temp = ((uint32_t)(GPIO_AF) << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4));
+ GPIOx->AFR[GPIO_PinSource >> 0x03] &= ~((uint32_t)0xF << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4));
+ temp_2 = GPIOx->AFR[GPIO_PinSource >> 0x03] | temp;
+ GPIOx->AFR[GPIO_PinSource >> 0x03] = temp_2;
+
+
+
+}
+
+/**
+ * @brief selects the IOMUX pin to used as Alternate function.
+ * @param GPIOx: where x can be (A, B, C, D) to select the GPIO peripheral.
+ * @param GPIO_PinSource: specifies the pin for the Alternate function.
+ * This parameter can be GPIO_PinSourcex where x can be (0..15) for GPIOA, GPIOB,GPIOB, GPIOD
+ * @param IOMUX_AF: selects the pin to used as Alternate function.
+ * This parameter can be one of the following value:
+ * GPIOMUX_AF_3_TIM1CH3
+ GPIOMUX_AF_3_TIM1CH1N
+ GPIOMUX_AF_3_TIM1CH4
+ GPIOMUX_AF_3_TIM1CH2N
+ GPIOMUX_AF0_SWCLK
+ GPIOMUX_AF0_I2C_SDA
+ * @retval None
+ */
+
+void GPIO_IOMUX_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t IOMUX_AF)
+{
+ /* Check the parameters */
+ assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
+ assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource));
+ assert_param(GPIO_IOMUX_AF(IOMUX_AF));
+ /* IOMUX function*/
+ // if PB5 as SWCLK
+ if((GPIOx == GPIOB)&&(GPIO_PinSource == GPIO_PinSource5))
+ {
+ if(IOMUX_AF == GPIOMUX_AF0_SWCLK)
+ {
+ GPIOMUX->PIN_FUNC_SEL |= IOMUX_PB5_SWCLK;
+ }
+ else if(IOMUX_AF == GPIOMUX_AF0_I2C_SDA)
+ {
+ GPIOMUX->PIN_FUNC_SEL &= IOMUX_PB5_SWCLK;
+ }
+ }
+ // select PC3 as TIM1 CH3 or CHIN
+ else if((GPIOx == GPIOC)&&(GPIO_PinSource == GPIO_PinSource3))
+ {
+
+ if(IOMUX_AF == GPIOMUX_AF3_TIM1CH3)
+ {
+ GPIOMUX->PIN_FUNC_SEL |= IOMUX_PC3_TIM1CH3;
+ }
+ else if(IOMUX_AF == GPIOMUX_AF3_TIM1CH1N)
+ {
+ GPIOMUX->PIN_FUNC_SEL &= IOMUX_PC3_TIM1CH1N;
+ }
+ }
+ // select PC4 as TIM1 CH4 or CH2N
+ else if((GPIOx == GPIOC)&&(GPIO_PinSource == GPIO_PinSource4))
+ {
+ if(IOMUX_AF == GPIOMUX_AF3_TIM1CH4)
+ {
+ GPIOMUX->PIN_FUNC_SEL |= IOMUX_PC4_TIM1CH4;
+ }
+ else if(IOMUX_AF == GPIOMUX_AF3_TIM1CH2N)
+ {
+ GPIOMUX->PIN_FUNC_SEL &= IOMUX_PC4_TIM1CH2N;
+ }
+ }
+
+}
+
+
+/**
+ * @brief change the pin to others IOMUX pin.
+ * @param eIOMUX_Pinx: where x can be (1 5 6 7 8) to select the GPIO pin.
+ * @param IOMUX_FuncPin: specifies the pin for the Alternate function.
+ * This parameter can be :
+ IOMUX_PD6_SEL_PD6
+ IOMUX_PD6_SEL_PA1
+ IOMUX_PD6_SEL_PD4
+ IOMUX_PD6_SEL_PA2
+
+ IOMUX_PB5_SEL_PB5
+ IOMUX_PB5_SEL_PA3
+ IOMUX_PB5_SEL_PD2
+
+ IOMUX_NRST_SEL_NRST
+ IOMUX_NRST_SEL_PA0
+ IOMUX_NRST_SEL_PB4
+
+ IOMUX_PC4_SEL_PC4
+ IOMUX_PC4_SEL_PC5
+ IOMUX_PC4_SEL_PC3
+ IOMUX_PC4_SEL_PC7
+
+ IOMUX_PD5_SEL_PD5
+ IOMUX_PD5_SEL_PD3
+ IOMUX_PD5_SEL_PD1
+ IOMUX_PD5_SEL_PC6
+
+ * @note The IOMUX_FuncPin parameter should from the list of IOMUX_FuncPin
+ * 1.nrst_pa0_sel can only be powered on reset
+ * 2. only when nrst_pin_key [15:0] = 0x5ae1 can be written by nrst_pa0_sel
+ * 3. When the cpu changes the value of pkg_pin_sel.nrstpa0_pin_sel or nrst_pa0_sel, the nrst_pin_key [15:0] is reset by the system hardware.
+ * @re None
+ */
+void GPIO_IOMUX_ChangePin(IOMUX_PIN eIOMUX_Pinx, uint32_t IOMUX_FuncPin)
+{
+ /* Check the parameters */
+ assert_param(IS_IOMUX_PIN(eIOMUX_Pinx));
+ assert_param(IS_IOMUX_PINFNC(IOMUX_FuncPin));
+
+ switch (eIOMUX_Pinx)
+ {
+ case IOMUX_PIN1:
+ #if defined HK32F030MJ4M6 //SOP 8 pin
+ GPIOMUX->PKG_PIN_SEL &= IOMUX_PD6_SEL_MASK;//clear select bits(7 8)
+ GPIOMUX->PKG_PIN_SEL |= IOMUX_FuncPin;
+ #elif defined HK32F030MD4P6 //SOP 16 pin
+ if((IOMUX_FuncPin == IOMUX_PD6_SEL_PD6)||(IOMUX_FuncPin == IOMUX_PD6_SEL_PD4))
+ {
+ GPIOMUX->PKG_PIN_SEL &= IOMUX_PD6_SEL_MASK;//clear select bits(7 8)
+ GPIOMUX->PKG_PIN_SEL |= IOMUX_FuncPin;
+ }
+ #endif
+ break;
+ case IOMUX_PIN2://TSSOP16
+ #if defined (HK32F030MD4P6)
+ if((IOMUX_FuncPin == IOMUX_NRST_SEL_PA0)||(IOMUX_FuncPin == IOMUX_NRST_SEL_NRST) )
+ {
+
+ GPIOMUX->NRST_PIN_KEY = NRST_PINKEY;
+ GPIOMUX->PKG_PIN_SEL &= IOMUX_NRST_SEL_MASK;//clear select bits(4 3)
+ GPIOMUX->NRST_PIN_KEY = NRST_PINKEY;
+ GPIOMUX->PKG_PIN_SEL |= IOMUX_NRST_SEL_PA0;
+
+ if(IOMUX_FuncPin == IOMUX_NRST_SEL_PA0)
+ {
+ GPIOMUX->NRST_PIN_KEY = NRST_PINKEY;
+ GPIOMUX->NRST_PA0_SEL |= (uint32_t)(0x00000001);
+ }
+ else
+ {
+ GPIOMUX->NRST_PIN_KEY = NRST_PINKEY;
+ GPIOMUX->NRST_PA0_SEL &= (uint32_t)(0x00000000);
+ }
+
+ }
+ #endif
+ break;
+ case IOMUX_PIN5:
+ #if defined HK32F030MJ4M6
+ GPIOMUX->PKG_PIN_SEL &= IOMUX_PB5_SEL_MASK;//clear select bits(2 1)
+ GPIOMUX->PKG_PIN_SEL |= IOMUX_FuncPin;
+ #endif
+ break;
+ case IOMUX_PIN6:
+ #if defined HK32F030MJ4M6
+ GPIOMUX->PKG_PIN_SEL &= IOMUX_PC4_SEL_MASK;//clear select bits(4 3 )
+ GPIOMUX->PKG_PIN_SEL |= IOMUX_FuncPin;
+ #endif
+ break;
+ case IOMUX_PIN7:
+ #if defined HK32F030MJ4M6
+ if((IOMUX_FuncPin == IOMUX_NRST_SEL_PA0)||(IOMUX_FuncPin == IOMUX_NRST_SEL_NRST))
+ {
+ GPIOMUX->NRST_PIN_KEY = NRST_PINKEY;
+ GPIOMUX->PKG_PIN_SEL &= IOMUX_NRST_SEL_MASK;//clear select bits(4 3)
+ GPIOMUX->NRST_PIN_KEY = NRST_PINKEY;
+ GPIOMUX->PKG_PIN_SEL |= IOMUX_NRST_SEL_PA0;
+ if(IOMUX_FuncPin == IOMUX_NRST_SEL_PA0)
+ {
+ GPIOMUX->NRST_PIN_KEY = NRST_PINKEY;
+ GPIOMUX->NRST_PA0_SEL |= (uint32_t)(0x00000001);
+ }
+ else
+ {
+ GPIOMUX->NRST_PIN_KEY = NRST_PINKEY;
+ GPIOMUX->NRST_PA0_SEL &= (uint32_t)(0x00000000);
+ }
+ }
+ else if(IOMUX_FuncPin == IOMUX_NRST_SEL_PB4)
+ {
+ GPIOMUX->NRST_PIN_KEY = NRST_PINKEY;
+ GPIOMUX->PKG_PIN_SEL &= IOMUX_NRST_SEL_MASK;//clear select bits(4 3)
+
+ GPIOMUX->NRST_PIN_KEY = NRST_PINKEY;
+ GPIOMUX->PKG_PIN_SEL |= IOMUX_FuncPin;
+ }
+ #endif
+
+ break;
+ case IOMUX_PIN8:
+ #if defined HK32F030MJ4M6
+ GPIOMUX->PKG_PIN_SEL &= IOMUX_PD5_SEL_MASK;//clear select bits (6 5)
+ GPIOMUX->PKG_PIN_SEL |= IOMUX_FuncPin;
+ #endif
+ break;
+ case IOMUX_PIN9:
+ #if defined HK32F030MD4P6
+ if((IOMUX_FuncPin == IOMUX_PB5_SEL_PB5)||(IOMUX_FuncPin == IOMUX_PB5_SEL_PD2))
+ {
+ GPIOMUX->PKG_PIN_SEL &= IOMUX_PB5_SEL_MASK;//clear select bits (6 5)
+ GPIOMUX->PKG_PIN_SEL |= IOMUX_FuncPin;
+ }
+ #endif
+ break;
+ case IOMUX_PIN11:
+ #if defined HK32F030MF4P6 || defined HK32F030MF4U6
+ GPIOMUX->PKG_PIN_SEL &= IOMUX_PB5_SEL_MASK;//clear select bits (6 5)
+ GPIOMUX->PKG_PIN_SEL |= IOMUX_FuncPin;
+ #endif
+ break;
+ case IOMUX_PIN12:
+ #if defined HK32F030MD4P6
+ if((IOMUX_FuncPin == IOMUX_PC4_SEL_PC4)||(IOMUX_FuncPin == IOMUX_PC4_SEL_PC7))
+ {
+ GPIOMUX->PKG_PIN_SEL &= IOMUX_PC4_SEL_MASK;//clear select bits (6 5)
+ GPIOMUX->PKG_PIN_SEL |= IOMUX_FuncPin;
+ }
+ #endif
+ break;
+ case IOMUX_PIN15:
+ #if defined HK32F030MD4P6
+ if((IOMUX_FuncPin == IOMUX_PD5_SEL_PD5)||(IOMUX_FuncPin == IOMUX_PD5_SEL_PD1))
+ {
+ GPIOMUX->PKG_PIN_SEL &= IOMUX_PD5_SEL_MASK;//clear select bits (6 5)
+ GPIOMUX->PKG_PIN_SEL |= IOMUX_FuncPin;
+ }
+ #endif
+
+ break;
+ default:
+ break;
+ }
+}
+
+
+
+/**
+ * @brief IOMUX select tim2 channel 1 input source.
+ * @param TIM2CN1Source:
+ * This parameter can be :
+ * TIM2_CN1_EXTERNAL
+ TIM2_CN1_HSIDIV
+ TIM2_CN1_LSI_128
+ TIM2_CN1_EXTERNAL_MAX
+ * */
+void GPIO_IOMUX_SetTIM2CN1_Source(TIM2_SOURCE TIM2CN1Source)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM2_SOURCE(TIM2CN1Source));
+ GPIOMUX->TIM2_CH0_IN_SEL = (uint32_t)TIM2CN1Source;
+}
+
+/**
+ * @}
+ */
+
+
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_i2c.c b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_i2c.c
new file mode 100644
index 0000000..a3a6a30
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_i2c.c
@@ -0,0 +1,1404 @@
+/**
+ ******************************************************************************
+ * @file hk32f030m_i2c.c
+ * @version V1.0.1
+ * author Rakan.z/wing.Wang
+ * @date 2019-12-16
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "hk32f030m_i2c.h"
+#include "hk32f030m_rcc.h"
+
+
+/** @defgroup I2C
+ * @brief I2C driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+
+#define CR1_CLEAR_MASK ((uint32_t)0x00CFE0FF) /*I2C_AnalogFilter));
+ assert_param(IS_I2C_DIGITAL_FILTER(I2C_InitStruct->I2C_DigitalFilter));
+ assert_param(IS_I2C_MODE(I2C_InitStruct->I2C_Mode));
+ assert_param(IS_I2C_OWN_ADDRESS1(I2C_InitStruct->I2C_OwnAddress1));
+ assert_param(IS_I2C_ACK(I2C_InitStruct->I2C_Ack));
+ assert_param(IS_I2C_ACKNOWLEDGE_ADDRESS(I2C_InitStruct->I2C_AcknowledgedAddress));
+
+ /* Disable I2Cx Peripheral */
+ I2Cx->CR1 &= (uint32_t)~((uint32_t)I2C_CR1_PE);
+
+ /*---------------------------- I2Cx FILTERS Configuration ------------------*/
+ /* Get the I2Cx CR1 value */
+ tmpreg = I2Cx->CR1;
+ /* Clear I2Cx CR1 register */
+ tmpreg &= CR1_CLEAR_MASK;
+ /* Configure I2Cx: analog and digital filter */
+ /* Set ANFOFF bit according to I2C_AnalogFilter value */
+ /* Set DFN bits according to I2C_DigitalFilter value */
+ tmpreg |= (uint32_t)I2C_InitStruct->I2C_AnalogFilter |(I2C_InitStruct->I2C_DigitalFilter << 8);
+
+ /* Write to I2Cx CR1 */
+ I2Cx->CR1 = tmpreg;
+
+ /*---------------------------- I2Cx TIMING Configuration -------------------*/
+ /* Configure I2Cx: Timing */
+ /* Set TIMINGR bits according to I2C_Timing */
+ /* Write to I2Cx TIMING */
+ I2Cx->TIMINGR = I2C_InitStruct->I2C_Timing & TIMING_CLEAR_MASK;
+
+ /* Enable I2Cx Peripheral */
+ I2Cx->CR1 |= I2C_CR1_PE;
+
+ /*---------------------------- I2Cx OAR1 Configuration ---------------------*/
+ /* Clear tmpreg local variable */
+ tmpreg = 0;
+ /* Clear OAR1 register */
+ I2Cx->OAR1 = (uint32_t)tmpreg;
+ /* Clear OAR2 register */
+ I2Cx->OAR2 = (uint32_t)tmpreg;
+ /* Configure I2Cx: Own Address1 and acknowledged address */
+ /* Set OA1MODE bit according to I2C_AcknowledgedAddress value */
+ /* Set OA1 bits according to I2C_OwnAddress1 value */
+ tmpreg = (uint32_t)((uint32_t)I2C_InitStruct->I2C_AcknowledgedAddress | \
+ (uint32_t)I2C_InitStruct->I2C_OwnAddress1);
+ /* Write to I2Cx OAR1 */
+ I2Cx->OAR1 = tmpreg;
+ /* Enable Own Address1 acknowledgement */
+ I2Cx->OAR1 |= I2C_OAR1_OA1EN;
+
+ /*---------------------------- I2Cx MODE Configuration ---------------------*/
+ /* Configure I2Cx: mode */
+ /* Set SMBDEN and SMBHEN bits according to I2C_Mode value */
+ tmpreg = I2C_InitStruct->I2C_Mode;
+ /* Write to I2Cx CR1 */
+ I2Cx->CR1 |= tmpreg;
+
+ /*---------------------------- I2Cx ACK Configuration ----------------------*/
+ /* Get the I2Cx CR2 value */
+ tmpreg = I2Cx->CR2;
+ /* Clear I2Cx CR2 register */
+ tmpreg &= CR2_CLEAR_MASK;
+ /* Configure I2Cx: acknowledgement */
+ /* Set NACK bit according to I2C_Ack value */
+ tmpreg |= I2C_InitStruct->I2C_Ack;
+ /* Write to I2Cx CR2 */
+ I2Cx->CR2 = tmpreg;
+}
+
+/**
+ * @brief Fills each I2C_InitStruct member with its default value.
+ * @param I2C_InitStruct: pointer to an I2C_InitTypeDef structure which will be initialized.
+ * @retval None
+ */
+void I2C_StructInit(I2C_InitTypeDef* I2C_InitStruct)
+{
+ /*---------------- Reset I2C init structure parameters values --------------*/
+ /* Initialize the I2C_Timing member */
+ I2C_InitStruct->I2C_Timing = 0;
+ /* Initialize the I2C_AnalogFilter member */
+ I2C_InitStruct->I2C_AnalogFilter = I2C_AnalogFilter_Enable;
+ /* Initialize the I2C_DigitalFilter member */
+ I2C_InitStruct->I2C_DigitalFilter = 0;
+ /* Initialize the I2C_Mode member */
+ I2C_InitStruct->I2C_Mode = I2C_Mode_I2C;
+ /* Initialize the I2C_OwnAddress1 member */
+ I2C_InitStruct->I2C_OwnAddress1 = 0;
+ /* Initialize the I2C_Ack member */
+ I2C_InitStruct->I2C_Ack = I2C_Ack_Disable;
+ /* Initialize the I2C_AcknowledgedAddress member */
+ I2C_InitStruct->I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
+}
+
+/**
+ * @brief Enables or disables the specified I2C peripheral.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the I2Cx peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected I2C peripheral */
+ I2Cx->CR1 |= I2C_CR1_PE;
+ }
+ else
+ {
+ /* Disable the selected I2C peripheral */
+ I2Cx->CR1 &= (uint32_t)~((uint32_t)I2C_CR1_PE);
+ }
+}
+
+/**
+ * @brief Enables or disables the specified I2C software reset.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @retval None
+ */
+void I2C_SoftwareResetCmd(I2C_TypeDef* I2Cx)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+
+ /* Disable peripheral */
+ I2Cx->CR1 &= (uint32_t)~((uint32_t)I2C_CR1_PE);
+
+ /* Perform a dummy read to delay the disable of peripheral for minimum
+ 3 APB clock cycles to perform the software reset functionality */
+ *(__IO uint32_t *)(uint32_t)I2Cx;
+
+ /* Enable peripheral */
+ I2Cx->CR1 |= I2C_CR1_PE;
+}
+
+/**
+ * @brief Enables or disables the specified I2C interrupts.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param I2C_IT: specifies the I2C interrupts sources to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * @arg I2C_IT_ERRI: Error interrupt mask
+ * @arg I2C_IT_TCI: Transfer Complete interrupt mask
+ * @arg I2C_IT_STOPI: Stop Detection interrupt mask
+ * @arg I2C_IT_NACKI: Not Acknowledge received interrupt mask
+ * @arg I2C_IT_ADDRI: Address Match interrupt mask
+ * @arg I2C_IT_RXI: RX interrupt mask
+ * @arg I2C_IT_TXI: TX interrupt mask
+ * @param NewState: new state of the specified I2C interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_ITConfig(I2C_TypeDef* I2Cx, uint32_t I2C_IT, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ assert_param(IS_I2C_CONFIG_IT(I2C_IT));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected I2C interrupts */
+ I2Cx->CR1 |= I2C_IT;
+ }
+ else
+ {
+ /* Disable the selected I2C interrupts */
+ I2Cx->CR1 &= (uint32_t)~((uint32_t)I2C_IT);
+ }
+}
+
+/**
+ * @brief Enables or disables the I2C Clock stretching.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the I2Cx Clock stretching.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_StretchClockCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable clock stretching */
+ I2Cx->CR1 &= (uint32_t)~((uint32_t)I2C_CR1_NOSTRETCH);
+ }
+ else
+ {
+ /* Disable clock stretching */
+ I2Cx->CR1 |= I2C_CR1_NOSTRETCH;
+ }
+}
+
+/**
+ * @brief Enables or disables I2C wakeup from stop mode.
+ * @param I2Cx: where x can be 1 to select the I2C peripheral.
+ * @param NewState: new state of the I2Cx stop mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_StopModeCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_1_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable wakeup from stop mode */
+ I2Cx->CR1 |= I2C_CR1_WUPEN;
+ }
+ else
+ {
+ /* Disable wakeup from stop mode */
+ I2Cx->CR1 &= (uint32_t)~((uint32_t)I2C_CR1_WUPEN);
+ }
+}
+
+/**
+ * @brief Enables or disables the I2C own address 2.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the I2C own address 2.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_DualAddressCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable own address 2 */
+ I2Cx->OAR2 |= I2C_OAR2_OA2EN;
+ }
+ else
+ {
+ /* Disable own address 2 */
+ I2Cx->OAR2 &= (uint32_t)~((uint32_t)I2C_OAR2_OA2EN);
+ }
+}
+
+/**
+ * @brief Configures the I2C slave own address 2 and mask.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param Address: specifies the slave address to be programmed.
+ * @param Mask: specifies own address 2 mask to be programmed.
+ * This parameter can be one of the following values:
+ * @arg I2C_OA2_NoMask: no mask.
+ * @arg I2C_OA2_Mask01: OA2[1] is masked and don't care.
+ * @arg I2C_OA2_Mask02: OA2[2:1] are masked and don't care.
+ * @arg I2C_OA2_Mask03: OA2[3:1] are masked and don't care.
+ * @arg I2C_OA2_Mask04: OA2[4:1] are masked and don't care.
+ * @arg I2C_OA2_Mask05: OA2[5:1] are masked and don't care.
+ * @arg I2C_OA2_Mask06: OA2[6:1] are masked and don't care.
+ * @arg I2C_OA2_Mask07: OA2[7:1] are masked and don't care.
+ * @retval None
+ */
+void I2C_OwnAddress2Config(I2C_TypeDef* I2Cx, uint16_t Address, uint8_t Mask)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_OWN_ADDRESS2(Address));
+ assert_param(IS_I2C_OWN_ADDRESS2_MASK(Mask));
+
+ /* Get the old register value */
+ tmpreg = I2Cx->OAR2;
+
+ /* Reset I2Cx OA2 bit [7:1] and OA2MSK bit [1:0] */
+ tmpreg &= (uint32_t)~((uint32_t)(I2C_OAR2_OA2 | I2C_OAR2_OA2MSK));
+
+ /* Set I2Cx SADD */
+ tmpreg |= (uint32_t)(((uint32_t)Address & I2C_OAR2_OA2) | \
+ (((uint32_t)Mask << 8) & I2C_OAR2_OA2MSK)) ;
+
+ /* Store the new register value */
+ I2Cx->OAR2 = tmpreg;
+}
+
+/**
+ * @brief Enables or disables the I2C general call mode.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the I2C general call mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_GeneralCallCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable general call mode */
+ I2Cx->CR1 |= I2C_CR1_GCEN;
+ }
+ else
+ {
+ /* Disable general call mode */
+ I2Cx->CR1 &= (uint32_t)~((uint32_t)I2C_CR1_GCEN);
+ }
+}
+
+/**
+ * @brief Enables or disables the I2C slave byte control.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the I2C slave byte control.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_SlaveByteControlCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable slave byte control */
+ I2Cx->CR1 |= I2C_CR1_SBC;
+ }
+ else
+ {
+ /* Disable slave byte control */
+ I2Cx->CR1 &= (uint32_t)~((uint32_t)I2C_CR1_SBC);
+ }
+}
+
+/**
+ * @brief Configures the slave address to be transmitted after start generation.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param Address: specifies the slave address to be programmed.
+ * @note This function should be called before generating start condition.
+ * @retval None
+ */
+void I2C_SlaveAddressConfig(I2C_TypeDef* I2Cx, uint16_t Address)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_SLAVE_ADDRESS(Address));
+
+ /* Get the old register value */
+ tmpreg = I2Cx->CR2;
+
+ /* Reset I2Cx SADD bit [9:0] */
+ tmpreg &= (uint32_t)~((uint32_t)I2C_CR2_SADD);
+
+ /* Set I2Cx SADD */
+ tmpreg |= (uint32_t)((uint32_t)Address & I2C_CR2_SADD);
+
+ /* Store the new register value */
+ I2Cx->CR2 = tmpreg;
+}
+
+/**
+ * @brief Enables or disables the I2C 10-bit addressing mode for the master.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the I2C 10-bit addressing mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @note This function should be called before generating start condition.
+ * @retval None
+ */
+void I2C_10BitAddressingModeCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable 10-bit addressing mode */
+ I2Cx->CR2 |= I2C_CR2_ADD10;
+ }
+ else
+ {
+ /* Disable 10-bit addressing mode */
+ I2Cx->CR2 &= (uint32_t)~((uint32_t)I2C_CR2_ADD10);
+ }
+}
+
+/**
+ * @}
+ */
+
+
+/** @defgroup I2C_Group2 Communications handling functions
+ * @brief Communications handling functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Communications handling functions #####
+ ===============================================================================
+ [..] This section provides a set of functions that handles I2C communication.
+
+ [..] Automatic End mode is enabled using I2C_AutoEndCmd() function. When Reload
+ mode is enabled via I2C_ReloadCmd() AutoEnd bit has no effect.
+
+ [..] I2C_NumberOfBytesConfig() function set the number of bytes to be transferred,
+ this configuration should be done before generating start condition in master
+ mode.
+
+ [..] When switching from master write operation to read operation in 10Bit addressing
+ mode, master can only sends the 1st 7 bits of the 10 bit address, followed by
+ Read direction by enabling HEADR bit using I2C_10BitAddressHeader() function.
+
+ [..] In master mode, when transferring more than 255 bytes Reload mode should be used
+ to handle communication. In the first phase of transfer, Nbytes should be set to
+ 255. After transferring these bytes TCR flag is set and I2C_TransferHandling()
+ function should be called to handle remaining communication.
+
+ [..] In master mode, when software end mode is selected when all data is transferred
+ TC flag is set I2C_TransferHandling() function should be called to generate STOP
+ or generate ReStart.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the I2C automatic end mode (stop condition is
+ * automatically sent when nbytes data are transferred).
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the I2C automatic end mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @note This function has effect if Reload mode is disabled.
+ * @retval None
+ */
+void I2C_AutoEndCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable Auto end mode */
+ I2Cx->CR2 |= I2C_CR2_AUTOEND;
+ }
+ else
+ {
+ /* Disable Auto end mode */
+ I2Cx->CR2 &= (uint32_t)~((uint32_t)I2C_CR2_AUTOEND);
+ }
+}
+
+/**
+ * @brief Enables or disables the I2C nbytes reload mode.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the nbytes reload mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_ReloadCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable Auto Reload mode */
+ I2Cx->CR2 |= I2C_CR2_RELOAD;
+ }
+ else
+ {
+ /* Disable Auto Reload mode */
+ I2Cx->CR2 &= (uint32_t)~((uint32_t)I2C_CR2_RELOAD);
+ }
+}
+
+/**
+ * @brief Configures the number of bytes to be transmitted/received.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param Number_Bytes: specifies the number of bytes to be programmed.
+ * @retval None
+ */
+void I2C_NumberOfBytesConfig(I2C_TypeDef* I2Cx, uint8_t Number_Bytes)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+
+ /* Get the old register value */
+ tmpreg = I2Cx->CR2;
+
+ /* Reset I2Cx Nbytes bit [7:0] */
+ tmpreg &= (uint32_t)~((uint32_t)I2C_CR2_NBYTES);
+
+ /* Set I2Cx Nbytes */
+ tmpreg |= (uint32_t)(((uint32_t)Number_Bytes << 16 ) & I2C_CR2_NBYTES);
+
+ /* Store the new register value */
+ I2Cx->CR2 = tmpreg;
+}
+
+/**
+ * @brief Configures the type of transfer request for the master.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param I2C_Direction: specifies the transfer request direction to be programmed.
+ * This parameter can be one of the following values:
+ * @arg I2C_Direction_Transmitter: Master request a write transfer
+ * @arg I2C_Direction_Receiver: Master request a read transfer
+ * @retval None
+ */
+void I2C_MasterRequestConfig(I2C_TypeDef* I2Cx, uint16_t I2C_Direction)
+{
+/* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_DIRECTION(I2C_Direction));
+
+ /* Test on the direction to set/reset the read/write bit */
+ if (I2C_Direction == I2C_Direction_Transmitter)
+ {
+ /* Request a write Transfer */
+ I2Cx->CR2 &= (uint32_t)~((uint32_t)I2C_CR2_RD_WRN);
+ }
+ else
+ {
+ /* Request a read Transfer */
+ I2Cx->CR2 |= I2C_CR2_RD_WRN;
+ }
+}
+
+/**
+ * @brief Generates I2Cx communication START condition.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the I2C START condition generation.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Generate a START condition */
+ I2Cx->CR2 |= I2C_CR2_START;
+ }
+ else
+ {
+ /* Disable the START condition generation */
+ I2Cx->CR2 &= (uint32_t)~((uint32_t)I2C_CR2_START);
+ }
+}
+
+/**
+ * @brief Generates I2Cx communication STOP condition.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the I2C STOP condition generation.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Generate a STOP condition */
+ I2Cx->CR2 |= I2C_CR2_STOP;
+ }
+ else
+ {
+ /* Disable the STOP condition generation */
+ I2Cx->CR2 &= (uint32_t)~((uint32_t)I2C_CR2_STOP);
+ }
+}
+
+/**
+ * @brief Enables or disables the I2C 10-bit header only mode with read direction.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the I2C 10-bit header only mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @note This mode can be used only when switching from master transmitter mode
+ * to master receiver mode.
+ * @retval None
+ */
+void I2C_10BitAddressHeaderCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable 10-bit header only mode */
+ I2Cx->CR2 |= I2C_CR2_HEAD10R;
+ }
+ else
+ {
+ /* Disable 10-bit header only mode */
+ I2Cx->CR2 &= (uint32_t)~((uint32_t)I2C_CR2_HEAD10R);
+ }
+}
+
+/**
+ * @brief Generates I2C communication Acknowledge.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the Acknowledge.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable ACK generation */
+ I2Cx->CR2 &= (uint32_t)~((uint32_t)I2C_CR2_NACK);
+ }
+ else
+ {
+ /* Enable NACK generation */
+ I2Cx->CR2 |= I2C_CR2_NACK;
+ }
+}
+
+/**
+ * @brief Returns the I2C slave matched address .
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @retval The value of the slave matched address .
+ */
+uint8_t I2C_GetAddressMatched(I2C_TypeDef* I2Cx)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+
+ /* Return the slave matched address in the SR1 register */
+ return (uint8_t)(((uint32_t)I2Cx->ISR & I2C_ISR_ADDCODE) >> 16) ;
+}
+
+/**
+ * @brief Returns the I2C slave received request.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @retval The value of the received request.
+ */
+uint16_t I2C_GetTransferDirection(I2C_TypeDef* I2Cx)
+{
+ uint32_t tmpreg = 0;
+ uint16_t direction = 0;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+
+ /* Return the slave matched address in the SR1 register */
+ tmpreg = (uint32_t)(I2Cx->ISR & I2C_ISR_DIR);
+
+ /* If write transfer is requested */
+ if (tmpreg == 0)
+ {
+ /* write transfer is requested */
+ direction = I2C_Direction_Transmitter;
+ }
+ else
+ {
+ /* Read transfer is requested */
+ direction = I2C_Direction_Receiver;
+ }
+ return direction;
+}
+
+/**
+ * @brief Handles I2Cx communication when starting transfer or during transfer (TC or TCR flag are set).
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param Address: specifies the slave address to be programmed.
+ * @param Number_Bytes: specifies the number of bytes to be programmed.
+ * This parameter must be a value between 0 and 255.
+ * @param ReloadEndMode: new state of the I2C START condition generation.
+ * This parameter can be one of the following values:
+ * @arg I2C_Reload_Mode: Enable Reload mode .
+ * @arg I2C_AutoEnd_Mode: Enable Automatic end mode.
+ * @arg I2C_SoftEnd_Mode: Enable Software end mode.
+ * @param StartStopMode: new state of the I2C START condition generation.
+ * This parameter can be one of the following values:
+ * @arg I2C_No_StartStop: Don't Generate stop and start condition.
+ * @arg I2C_Generate_Stop: Generate stop condition (Number_Bytes should be set to 0).
+ * @arg I2C_Generate_Start_Read: Generate Restart for read request.
+ * @arg I2C_Generate_Start_Write: Generate Restart for write request.
+ * @retval None
+ */
+void I2C_TransferHandling(I2C_TypeDef* I2Cx, uint16_t Address, uint8_t Number_Bytes, uint32_t ReloadEndMode, uint32_t StartStopMode)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_SLAVE_ADDRESS(Address));
+ assert_param(IS_RELOAD_END_MODE(ReloadEndMode));
+ assert_param(IS_START_STOP_MODE(StartStopMode));
+
+ /* Get the CR2 register value */
+ tmpreg = I2Cx->CR2;
+
+ /* clear tmpreg specific bits */
+ tmpreg &= (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP));
+
+ /* update tmpreg */
+ tmpreg |= (uint32_t)(((uint32_t)Address & I2C_CR2_SADD) | (((uint32_t)Number_Bytes << 16 ) & I2C_CR2_NBYTES) | \
+ (uint32_t)ReloadEndMode | (uint32_t)StartStopMode);
+
+ /* update CR2 register */
+ I2Cx->CR2 = tmpreg;
+}
+
+/**
+ * @}
+ */
+
+
+/** @defgroup I2C_Group3 SMBUS management functions
+ * @brief SMBUS management functions
+ *
+@verbatim
+ ===============================================================================
+ ##### SMBUS management functions #####
+ ===============================================================================
+ [..] This section provides a set of functions that handles SMBus communication
+ and timeouts detection.
+
+ [..] The SMBus Device default address (0b1100 001) is enabled by calling I2C_Init()
+ function and setting I2C_Mode member of I2C_InitTypeDef() structure to
+ I2C_Mode_SMBusDevice.
+
+ [..] The SMBus Host address (0b0001 000) is enabled by calling I2C_Init()
+ function and setting I2C_Mode member of I2C_InitTypeDef() structure to
+ I2C_Mode_SMBusHost.
+
+ [..] The Alert Response Address (0b0001 100) is enabled using I2C_SMBusAlertCmd()
+ function.
+
+ [..] To detect cumulative SCL stretch in master and slave mode, TIMEOUTB should be
+ configured (in accordance to SMBus specification) using I2C_TimeoutBConfig()
+ function then I2C_ExtendedClockTimeoutCmd() function should be called to enable
+ the detection.
+
+ [..] SCL low timeout is detected by configuring TIMEOUTB using I2C_TimeoutBConfig()
+ function followed by the call of I2C_ClockTimeoutCmd(). When adding to this
+ procedure the call of I2C_IdleClockTimeoutCmd() function, Bus Idle condition
+ (both SCL and SDA high) is detected also.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables I2C SMBus alert.
+ * @param I2Cx: where x can be 1 to select the I2C peripheral.
+ * @param NewState: new state of the I2Cx SMBus alert.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_SMBusAlertCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_1_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable SMBus alert */
+ I2Cx->CR1 |= I2C_CR1_ALERTEN;
+ }
+ else
+ {
+ /* Disable SMBus alert */
+ I2Cx->CR1 &= (uint32_t)~((uint32_t)I2C_CR1_ALERTEN);
+ }
+}
+
+/**
+ * @brief Enables or disables I2C Clock Timeout (SCL Timeout detection).
+ * @param I2Cx: where x can be 1 to select the I2C peripheral.
+ * @param NewState: new state of the I2Cx clock Timeout.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_ClockTimeoutCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_1_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable Clock Timeout */
+ I2Cx->TIMEOUTR |= I2C_TIMEOUTR_TIMOUTEN;
+ }
+ else
+ {
+ /* Disable Clock Timeout */
+ I2Cx->TIMEOUTR &= (uint32_t)~((uint32_t)I2C_TIMEOUTR_TIMOUTEN);
+ }
+}
+
+/**
+ * @brief Enables or disables I2C Extended Clock Timeout (SCL cumulative Timeout detection).
+ * @param I2Cx: where x can be 1 to select the I2C peripheral.
+ * @param NewState: new state of the I2Cx Extended clock Timeout.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_ExtendedClockTimeoutCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_1_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable Clock Timeout */
+ I2Cx->TIMEOUTR |= I2C_TIMEOUTR_TEXTEN;
+ }
+ else
+ {
+ /* Disable Clock Timeout */
+ I2Cx->TIMEOUTR &= (uint32_t)~((uint32_t)I2C_TIMEOUTR_TEXTEN);
+ }
+}
+
+/**
+ * @brief Enables or disables I2C Idle Clock Timeout (Bus idle SCL and SDA
+ * high detection).
+ * @param I2Cx: where x can be 1 to select the I2C peripheral.
+ * @param NewState: new state of the I2Cx Idle clock Timeout.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_IdleClockTimeoutCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_1_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable Clock Timeout */
+ I2Cx->TIMEOUTR |= I2C_TIMEOUTR_TIDLE;
+ }
+ else
+ {
+ /* Disable Clock Timeout */
+ I2Cx->TIMEOUTR &= (uint32_t)~((uint32_t)I2C_TIMEOUTR_TIDLE);
+ }
+}
+
+/**
+ * @brief Configures the I2C Bus Timeout A (SCL Timeout when TIDLE = 0 or Bus
+ * idle SCL and SDA high when TIDLE = 1).
+ * @param I2Cx: where x can be 1 to select the I2C peripheral.
+ * @param Timeout: specifies the TimeoutA to be programmed.
+ * @retval None
+ */
+void I2C_TimeoutAConfig(I2C_TypeDef* I2Cx, uint16_t Timeout)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_1_PERIPH(I2Cx));
+ assert_param(IS_I2C_TIMEOUT(Timeout));
+
+ /* Get the old register value */
+ tmpreg = I2Cx->TIMEOUTR;
+
+ /* Reset I2Cx TIMEOUTA bit [11:0] */
+ tmpreg &= (uint32_t)~((uint32_t)I2C_TIMEOUTR_TIMEOUTA);
+
+ /* Set I2Cx TIMEOUTA */
+ tmpreg |= (uint32_t)((uint32_t)Timeout & I2C_TIMEOUTR_TIMEOUTA) ;
+
+ /* Store the new register value */
+ I2Cx->TIMEOUTR = tmpreg;
+}
+
+/**
+ * @brief Configures the I2C Bus Timeout B (SCL cumulative Timeout).
+ * @param I2Cx: where x can be 1 to select the I2C peripheral.
+ * @param Timeout: specifies the TimeoutB to be programmed.
+ * @retval None
+ */
+void I2C_TimeoutBConfig(I2C_TypeDef* I2Cx, uint16_t Timeout)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_1_PERIPH(I2Cx));
+ assert_param(IS_I2C_TIMEOUT(Timeout));
+
+ /* Get the old register value */
+ tmpreg = I2Cx->TIMEOUTR;
+
+ /* Reset I2Cx TIMEOUTB bit [11:0] */
+ tmpreg &= (uint32_t)~((uint32_t)I2C_TIMEOUTR_TIMEOUTB);
+
+ /* Set I2Cx TIMEOUTB */
+ tmpreg |= (uint32_t)(((uint32_t)Timeout << 16) & I2C_TIMEOUTR_TIMEOUTB) ;
+
+ /* Store the new register value */
+ I2Cx->TIMEOUTR = tmpreg;
+}
+
+/**
+ * @brief Enables or disables I2C PEC calculation.
+ * @param I2Cx: where x can be 1 to select the I2C peripheral.
+ * @param NewState: new state of the I2Cx PEC calculation.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_CalculatePEC(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_1_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable PEC calculation */
+ I2Cx->CR1 |= I2C_CR1_PECEN;
+ }
+ else
+ {
+ /* Disable PEC calculation */
+ I2Cx->CR1 &= (uint32_t)~((uint32_t)I2C_CR1_PECEN);
+ }
+}
+
+/**
+ * @brief Enables or disables I2C PEC transmission/reception request.
+ * @param I2Cx: where x can be 1 to select the I2C peripheral.
+ * @param NewState: new state of the I2Cx PEC request.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_PECRequestCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_1_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable PEC transmission/reception request */
+ I2Cx->CR2 |= I2C_CR2_PECBYTE;
+ }
+ else
+ {
+ /* Disable PEC transmission/reception request */
+ I2Cx->CR2 &= (uint32_t)~((uint32_t)I2C_CR2_PECBYTE);
+ }
+}
+
+/**
+ * @brief Returns the I2C PEC.
+ * @param I2Cx: where x can be 1 to select the I2C peripheral.
+ * @retval The value of the PEC .
+ */
+uint8_t I2C_GetPEC(I2C_TypeDef* I2Cx)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_1_PERIPH(I2Cx));
+
+ /* Return the slave matched address in the SR1 register */
+ return (uint8_t)((uint32_t)I2Cx->PECR & I2C_PECR_PEC);
+}
+
+/**
+ * @}
+ */
+
+
+/** @defgroup I2C_Group4 I2C registers management functions
+ * @brief I2C registers management functions
+ *
+@verbatim
+ ===============================================================================
+ ##### I2C registers management functions #####
+ ===============================================================================
+ [..] This section provides a functions that allow user the management of
+ I2C registers.
+
+@endverbatim
+ * @{
+ */
+
+ /**
+ * @brief Reads the specified I2C register and returns its value.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param I2C_Register: specifies the register to read.
+ * This parameter can be one of the following values:
+ * @arg I2C_Register_CR1: CR1 register.
+ * @arg I2C_Register_CR2: CR2 register.
+ * @arg I2C_Register_OAR1: OAR1 register.
+ * @arg I2C_Register_OAR2: OAR2 register.
+ * @arg I2C_Register_TIMINGR: TIMING register.
+ * @arg I2C_Register_TIMEOUTR: TIMEOUTR register.
+ * @arg I2C_Register_ISR: ISR register.
+ * @arg I2C_Register_ICR: ICR register.
+ * @arg I2C_Register_PECR: PECR register.
+ * @arg I2C_Register_RXDR: RXDR register.
+ * @arg I2C_Register_TXDR: TXDR register.
+ * @retval The value of the read register.
+ */
+uint32_t I2C_ReadRegister(I2C_TypeDef* I2Cx, uint8_t I2C_Register)
+{
+ __IO uint32_t tmp = 0;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_REGISTER(I2C_Register));
+
+ tmp = (uint32_t)I2Cx;
+ tmp += I2C_Register;
+
+ /* Return the selected register value */
+ return (*(__IO uint32_t *) tmp);
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup I2C_Group5 Data transfers management functions
+ * @brief Data transfers management functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Data transfers management functions #####
+ ===============================================================================
+ [..] This subsection provides a set of functions allowing to manage
+ the I2C data transfers.
+
+ [..] The read access of the I2C_RXDR register can be done using
+ the I2C_ReceiveData() function and returns the received value.
+ Whereas a write access to the I2C_TXDR can be done using I2C_SendData()
+ function and stores the written data into TXDR.
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Sends a data byte through the I2Cx peripheral.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param Data: Byte to be transmitted..
+ * @retval None
+ */
+void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+
+ /* Write in the DR register the data to be sent */
+ I2Cx->TXDR = (uint8_t)Data;
+}
+
+/**
+ * @brief Returns the most recent received data by the I2Cx peripheral.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @retval The value of the received data.
+ */
+uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+
+ /* Return the data in the DR register */
+ return (uint8_t)I2Cx->RXDR;
+}
+
+/**
+ * @}
+ */
+
+
+/** @defgroup I2C_Group6 DMA transfers management functions
+ * @brief DMA transfers management functions
+ *
+ ===============================================================================
+ ##### Interrupts and flags management functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to configure the I2C Interrupts
+ sources and check or clear the flags or pending bits status.
+ The user should identify which mode will be used in his application to manage
+ the communication: Polling mode, Interrupt mode or DMA mode(refer I2C_Group6).
+
+ *** Polling Mode ***
+ ====================
+ [..] In Polling Mode, the I2C communication can be managed by 15 flags:
+ (#) I2C_FLAG_TXE: to indicate the status of Transmit data register empty flag.
+ (#) I2C_FLAG_TXIS: to indicate the status of Transmit interrupt status flag .
+ (#) I2C_FLAG_RXNE: to indicate the status of Receive data register not empty flag.
+ (#) I2C_FLAG_ADDR: to indicate the status of Address matched flag (slave mode).
+ (#) I2C_FLAG_NACKF: to indicate the status of NACK received flag.
+ (#) I2C_FLAG_STOPF: to indicate the status of STOP detection flag.
+ (#) I2C_FLAG_TC: to indicate the status of Transfer complete flag(master mode).
+ (#) I2C_FLAG_TCR: to indicate the status of Transfer complete reload flag.
+ (#) I2C_FLAG_BERR: to indicate the status of Bus error flag.
+ (#) I2C_FLAG_ARLO: to indicate the status of Arbitration lost flag.
+ (#) I2C_FLAG_OVR: to indicate the status of Overrun/Underrun flag.
+ (#) I2C_FLAG_PECERR: to indicate the status of PEC error in reception flag.
+ (#) I2C_FLAG_TIMEOUT: to indicate the status of Timeout or Tlow detection flag.
+ (#) I2C_FLAG_ALERT: to indicate the status of SMBus Alert flag.
+ (#) I2C_FLAG_BUSY: to indicate the status of Bus busy flag.
+
+ [..] In this Mode it is advised to use the following functions:
+ (+) FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG);
+ (+) void I2C_ClearFlag(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG);
+
+ [..]
+ (@)Do not use the BUSY flag to handle each data transmission or reception.It is
+ better to use the TXIS and RXNE flags instead.
+
+ *** Interrupt Mode ***
+ ======================
+ [..] In Interrupt Mode, the I2C communication can be managed by 7 interrupt sources
+ and 15 pending bits:
+ [..] Interrupt Source:
+ (#) I2C_IT_ERRI: specifies the interrupt source for the Error interrupt.
+ (#) I2C_IT_TCI: specifies the interrupt source for the Transfer Complete interrupt.
+ (#) I2C_IT_STOPI: specifies the interrupt source for the Stop Detection interrupt.
+ (#) I2C_IT_NACKI: specifies the interrupt source for the Not Acknowledge received interrupt.
+ (#) I2C_IT_ADDRI: specifies the interrupt source for the Address Match interrupt.
+ (#) I2C_IT_RXI: specifies the interrupt source for the RX interrupt.
+ (#) I2C_IT_TXI: specifies the interrupt source for the TX interrupt.
+
+ [..] Pending Bits:
+ (#) I2C_IT_TXIS: to indicate the status of Transmit interrupt status flag.
+ (#) I2C_IT_RXNE: to indicate the status of Receive data register not empty flag.
+ (#) I2C_IT_ADDR: to indicate the status of Address matched flag (slave mode).
+ (#) I2C_IT_NACKF: to indicate the status of NACK received flag.
+ (#) I2C_IT_STOPF: to indicate the status of STOP detection flag.
+ (#) I2C_IT_TC: to indicate the status of Transfer complete flag (master mode).
+ (#) I2C_IT_TCR: to indicate the status of Transfer complete reload flag.
+ (#) I2C_IT_BERR: to indicate the status of Bus error flag.
+ (#) I2C_IT_ARLO: to indicate the status of Arbitration lost flag.
+ (#) I2C_IT_OVR: to indicate the status of Overrun/Underrun flag.
+ (#) I2C_IT_PECERR: to indicate the status of PEC error in reception flag.
+ (#) I2C_IT_TIMEOUT: to indicate the status of Timeout or Tlow detection flag.
+ (#) I2C_IT_ALERT: to indicate the status of SMBus Alert flag.
+
+ [..] In this Mode it is advised to use the following functions:
+ (+) void I2C_ClearITPendingBit(I2C_TypeDef* I2Cx, uint32_t I2C_IT);
+ (+) ITStatus I2C_GetITStatus(I2C_TypeDef* I2Cx, uint32_t I2C_IT);
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Checks whether the specified I2C flag is set or not.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param I2C_FLAG: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg I2C_FLAG_TXE: Transmit data register empty
+ * @arg I2C_FLAG_TXIS: Transmit interrupt status
+ * @arg I2C_FLAG_RXNE: Receive data register not empty
+ * @arg I2C_FLAG_ADDR: Address matched (slave mode)
+ * @arg I2C_FLAG_NACKF: NACK received flag
+ * @arg I2C_FLAG_STOPF: STOP detection flag
+ * @arg I2C_FLAG_TC: Transfer complete (master mode)
+ * @arg I2C_FLAG_TCR: Transfer complete reload
+ * @arg I2C_FLAG_BERR: Bus error
+ * @arg I2C_FLAG_ARLO: Arbitration lost
+ * @arg I2C_FLAG_OVR: Overrun/Underrun
+ * @arg I2C_FLAG_PECERR: PEC error in reception
+ * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow detection flag
+ * @arg I2C_FLAG_ALERT: SMBus Alert
+ * @arg I2C_FLAG_BUSY: Bus busy
+ * @retval The new state of I2C_FLAG (SET or RESET).
+ */
+FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG)
+{
+ uint32_t tmpreg = 0;
+ FlagStatus bitstatus = RESET;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_GET_FLAG(I2C_FLAG));
+
+ /* Get the ISR register value */
+ tmpreg = I2Cx->ISR;
+
+ /* Get flag status */
+ tmpreg &= I2C_FLAG;
+
+ if(tmpreg != 0)
+ {
+ /* I2C_FLAG is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* I2C_FLAG is reset */
+ bitstatus = RESET;
+ }
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the I2Cx's pending flags.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param I2C_FLAG: specifies the flag to clear.
+ * This parameter can be any combination of the following values:
+ * @arg I2C_FLAG_ADDR: Address matched (slave mode)
+ * @arg I2C_FLAG_NACKF: NACK received flag
+ * @arg I2C_FLAG_STOPF: STOP detection flag
+ * @arg I2C_FLAG_BERR: Bus error
+ * @arg I2C_FLAG_ARLO: Arbitration lost
+ * @arg I2C_FLAG_OVR: Overrun/Underrun
+ * @arg I2C_FLAG_PECERR: PEC error in reception
+ * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow detection flag
+ * @arg I2C_FLAG_ALERT: SMBus Alert
+ * @retval The new state of I2C_FLAG (SET or RESET).
+ */
+void I2C_ClearFlag(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_CLEAR_FLAG(I2C_FLAG));
+
+ /* Clear the selected flag */
+ I2Cx->ICR = I2C_FLAG;
+ }
+
+/**
+ * @brief Checks whether the specified I2C interrupt has occurred or not.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param I2C_IT: specifies the interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg I2C_IT_TXIS: Transmit interrupt status
+ * @arg I2C_IT_RXNE: Receive data register not empty
+ * @arg I2C_IT_ADDR: Address matched (slave mode)
+ * @arg I2C_IT_NACKF: NACK received flag
+ * @arg I2C_IT_STOPF: STOP detection flag
+ * @arg I2C_IT_TC: Transfer complete (master mode)
+ * @arg I2C_IT_TCR: Transfer complete reload
+ * @arg I2C_IT_BERR: Bus error
+ * @arg I2C_IT_ARLO: Arbitration lost
+ * @arg I2C_IT_OVR: Overrun/Underrun
+ * @arg I2C_IT_PECERR: PEC error in reception
+ * @arg I2C_IT_TIMEOUT: Timeout or Tlow detection flag
+ * @arg I2C_IT_ALERT: SMBus Alert
+ * @retval The new state of I2C_IT (SET or RESET).
+ */
+ITStatus I2C_GetITStatus(I2C_TypeDef* I2Cx, uint32_t I2C_IT)
+{
+ uint32_t tmpreg = 0;
+ ITStatus bitstatus = RESET;
+ uint32_t enablestatus = 0;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_GET_IT(I2C_IT));
+
+ /* Check if the interrupt source is enabled or not */
+ /* If Error interrupt */
+ if ((uint32_t)(I2C_IT & ERROR_IT_MASK))
+ {
+ enablestatus = (uint32_t)((I2C_CR1_ERRIE) & (I2Cx->CR1));
+ }
+ /* If TC interrupt */
+ else if ((uint32_t)(I2C_IT & TC_IT_MASK))
+ {
+ enablestatus = (uint32_t)((I2C_CR1_TCIE) & (I2Cx->CR1));
+ }
+ else
+ {
+ enablestatus = (uint32_t)((I2C_IT) & (I2Cx->CR1));
+ }
+
+ /* Get the ISR register value */
+ tmpreg = I2Cx->ISR;
+
+ /* Get flag status */
+ tmpreg &= I2C_IT;
+
+ /* Check the status of the specified I2C flag */
+ if((tmpreg != RESET) && enablestatus)
+ {
+ /* I2C_IT is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* I2C_IT is reset */
+ bitstatus = RESET;
+ }
+
+ /* Return the I2C_IT status */
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the I2Cx's interrupt pending bits.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param I2C_IT: specifies the interrupt pending bit to clear.
+ * This parameter can be any combination of the following values:
+ * @arg I2C_IT_ADDR: Address matched (slave mode)
+ * @arg I2C_IT_NACKF: NACK received flag
+ * @arg I2C_IT_STOPF: STOP detection flag
+ * @arg I2C_IT_BERR: Bus error
+ * @arg I2C_IT_ARLO: Arbitration lost
+ * @arg I2C_IT_OVR: Overrun/Underrun
+ * @arg I2C_IT_PECERR: PEC error in reception
+ * @arg I2C_IT_TIMEOUT: Timeout or Tlow detection flag
+ * @arg I2C_IT_ALERT: SMBus Alert
+ * @retval The new state of I2C_IT (SET or RESET).
+ */
+void I2C_ClearITPendingBit(I2C_TypeDef* I2Cx, uint32_t I2C_IT)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_CLEAR_IT(I2C_IT));
+
+ /* Clear the selected flag */
+ I2Cx->ICR = I2C_IT;
+}
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_iwdg.c b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_iwdg.c
new file mode 100644
index 0000000..eb6d4a1
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_iwdg.c
@@ -0,0 +1,201 @@
+/**
+ ******************************************************************************
+ * @file hk32f030m_iwdg.c
+ * @version V1.0.1
+ * author Rakan.Z/wing.Wang
+ * @date 2019-12-17
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "hk32f030m_iwdg.h"
+
+
+/** @defgroup IWDG
+ * @brief IWDG driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* ---------------------- IWDG registers bit mask ----------------------------*/
+/* KR register bit mask */
+#define KR_KEY_RELOAD ((uint16_t)0xAAAA)
+#define KR_KEY_ENABLE ((uint16_t)0xCCCC)
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup IWDG_Private_Functions
+ * @{
+ */
+
+/** @defgroup IWDG_Group1 Prescaler and Counter configuration functions
+ * @brief Prescaler and Counter configuration functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Prescaler and Counter configuration functions #####
+ ==============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables write access to IWDG_PR and IWDG_RLR registers.
+ * @param IWDG_WriteAccess: new state of write access to IWDG_PR and IWDG_RLR registers.
+ * This parameter can be one of the following values:
+ * @arg IWDG_WriteAccess_Enable: Enable write access to IWDG_PR and IWDG_RLR registers
+ * @arg IWDG_WriteAccess_Disable: Disable write access to IWDG_PR and IWDG_RLR registers
+ * @retval None
+ */
+void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess)
+{
+ /* Check the parameters */
+ assert_param(IS_IWDG_WRITE_ACCESS(IWDG_WriteAccess));
+ IWDG->KR = IWDG_WriteAccess;
+}
+
+/**
+ * @brief Sets IWDG Prescaler value.
+ * @param IWDG_Prescaler: specifies the IWDG Prescaler value.
+ * This parameter can be one of the following values:
+ * @arg IWDG_Prescaler_4: IWDG prescaler set to 4
+ * @arg IWDG_Prescaler_8: IWDG prescaler set to 8
+ * @arg IWDG_Prescaler_16: IWDG prescaler set to 16
+ * @arg IWDG_Prescaler_32: IWDG prescaler set to 32
+ * @arg IWDG_Prescaler_64: IWDG prescaler set to 64
+ * @arg IWDG_Prescaler_128: IWDG prescaler set to 128
+ * @arg IWDG_Prescaler_256: IWDG prescaler set to 256
+ * @retval None
+ */
+void IWDG_SetPrescaler(uint8_t IWDG_Prescaler)
+{
+ /* Check the parameters */
+ assert_param(IS_IWDG_PRESCALER(IWDG_Prescaler));
+ IWDG->PR = IWDG_Prescaler;
+}
+
+/**
+ * @brief Sets IWDG Reload value.
+ * @param Reload: specifies the IWDG Reload value.
+ * This parameter must be a number between 0 and 0x0FFF.
+ * @retval None
+ */
+void IWDG_SetReload(uint16_t Reload)
+{
+ /* Check the parameters */
+ assert_param(IS_IWDG_RELOAD(Reload));
+ IWDG->RLR = Reload;
+}
+
+/**
+ * @brief Reloads IWDG counter with value defined in the reload register
+ * (write access to IWDG_PR and IWDG_RLR registers disabled).
+ * @param None
+ * @retval None
+ */
+void IWDG_ReloadCounter(void)
+{
+ IWDG->KR = KR_KEY_RELOAD;
+}
+
+
+/**
+ * @brief Sets the IWDG window value.
+ * @param WindowValue: specifies the window value to be compared to the downcounter.
+ * @retval None
+ */
+void IWDG_SetWindowValue(uint16_t WindowValue)
+{
+ /* Check the parameters */
+ assert_param(IS_IWDG_WINDOW_VALUE(WindowValue));
+ IWDG->WINR = WindowValue;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup IWDG_Group2 IWDG activation function
+ * @brief IWDG activation function
+ *
+@verbatim
+ ==============================================================================
+ ##### IWDG activation function #####
+ ==============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables IWDG (write access to IWDG_PR and IWDG_RLR registers disabled).
+ * @param None
+ * @retval None
+ */
+void IWDG_Enable(void)
+{
+ IWDG->KR = KR_KEY_ENABLE;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup IWDG_Group3 Flag management function
+ * @brief Flag management function
+ *
+@verbatim
+ ===============================================================================
+ ##### Flag management function #####
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Checks whether the specified IWDG flag is set or not.
+ * @param IWDG_FLAG: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg IWDG_FLAG_PVU: Prescaler Value Update on going
+ * @arg IWDG_FLAG_RVU: Reload Value Update on going
+ * @arg IWDG_FLAG_WVU: Counter Window Value Update on going
+ * @retval The new state of IWDG_FLAG (SET or RESET).
+ */
+FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG)
+{
+ FlagStatus bitstatus = RESET;
+ /* Check the parameters */
+ assert_param(IS_IWDG_FLAG(IWDG_FLAG));
+ if ((IWDG->SR & IWDG_FLAG) != (uint32_t)RESET)
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+ /* Return the flag status */
+ return bitstatus;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_misc.c b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_misc.c
new file mode 100644
index 0000000..2eece5f
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_misc.c
@@ -0,0 +1,141 @@
+/**
+ ******************************************************************************
+ * @file hk32f030m_misc.c
+ * @author Rakan.z
+ * @version V1.0
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "hk32f030m_misc.h"
+
+
+/** @defgroup MISC
+ * @brief MISC driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup MISC_Private_Functions
+ * @{
+ */
+/**
+ *
+@verbatim
+ *******************************************************************************
+ ##### Interrupts configuration functions #####
+ *******************************************************************************
+ [..] This section provide functions allowing to configure the NVIC interrupts
+ (IRQ). The Cortex-M0 exceptions are managed by CMSIS functions.
+ (#) Enable and Configure the priority of the selected IRQ Channels.
+ The priority can be 0..3.
+
+ -@- Lower priority values gives higher priority.
+ -@- Priority Order:
+ (#@) Lowest priority.
+ (#@) Lowest hardware priority (IRQn position).
+
+@endverbatim
+*/
+
+/**
+ * @brief Initializes the NVIC peripheral according to the specified
+ * parameters in the NVIC_InitStruct.
+ * @param NVIC_InitStruct: pointer to a NVIC_InitTypeDef structure that contains
+ * the configuration information for the specified NVIC peripheral.
+ * @retval None
+ */
+void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)
+{
+ uint32_t tmppriority = 0x00;
+
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NVIC_InitStruct->NVIC_IRQChannelCmd));
+ assert_param(IS_NVIC_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelPriority));
+
+ if (NVIC_InitStruct->NVIC_IRQChannelCmd != DISABLE)
+ {
+ /* Compute the Corresponding IRQ Priority --------------------------------*/
+ tmppriority = NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel >> 0x02];
+ tmppriority &= (uint32_t)(~(((uint32_t)0xFF) << ((NVIC_InitStruct->NVIC_IRQChannel & 0x03) * 8)));
+ tmppriority |= (uint32_t)((((uint32_t)NVIC_InitStruct->NVIC_IRQChannelPriority << 6) & 0xFF) << ((NVIC_InitStruct->NVIC_IRQChannel & 0x03) * 8));
+
+ NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel >> 0x02] = tmppriority;
+
+ /* Enable the Selected IRQ Channels --------------------------------------*/
+ NVIC->ISER[0] = (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F);
+ }
+ else
+ {
+ /* Disable the Selected IRQ Channels -------------------------------------*/
+ NVIC->ICER[0] = (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F);
+ }
+}
+
+
+/**
+ * @brief Selects the condition for the system to enter low power mode.
+ * @param LowPowerMode: Specifies the new mode for the system to enter low power mode.
+ * This parameter can be one of the following values:
+ * @arg NVIC_LP_SEVONPEND: Low Power SEV on Pend.
+ * @arg NVIC_LP_SLEEPDEEP: Low Power DEEPSLEEP request.
+ * @arg NVIC_LP_SLEEPONEXIT: Low Power Sleep on Exit.
+ * @param NewState: new state of LP condition.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_NVIC_LP(LowPowerMode));
+
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ SCB->SCR |= LowPowerMode;
+ }
+ else
+ {
+ SCB->SCR &= (uint32_t)(~(uint32_t)LowPowerMode);
+ }
+}
+
+/**
+ * @brief Configures the SysTick clock source.
+ * @param SysTick_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 SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)
+{
+ /* Check the parameters */
+ assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource));
+
+ if (SysTick_CLKSource == SysTick_CLKSource_HCLK)
+ {
+ SysTick->CTRL |= SysTick_CLKSource_HCLK;
+ }
+ else
+ {
+ SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8;
+ }
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_pwr.c b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_pwr.c
new file mode 100644
index 0000000..1561dfe
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_pwr.c
@@ -0,0 +1,211 @@
+/*
+ ******************************************************************************
+ * @file hk32f030m_pwr.c
+ * @author Rakan.z
+ * @version V1.0
+ * @brief API file of PWR module
+ * @changelist
+ ******************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include
+#include
+#include
+/** @defgroup PWR_Private_Defines
+ * @{
+ */
+
+
+
+/**
+ * @brief Deinitializes the PWR peripheral registers to their default reset values.
+ * @param None
+ * @retval None
+ */
+void PWR_DeInit(void)
+{
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_PWR, ENABLE);
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_PWR, DISABLE);
+}
+
+
+
+/**
+ * @brief Enters Sleep mode.
+ * @param PWR_Entry: specifies if Sleep mode in entered with WFI or WFE instruction.
+ * This parameter can be one of the following values:
+ * @arg PWR_Entry_WFI: enter Sleep mode with WFI instruction
+ * @arg PWR_Entry_WFE: enter Sleep mode with WFE instruction
+ * @retval None
+ */
+void PWR_EnterSleepMode(uint8_t PWR_Entry)
+{
+ uint32_t tmpreg = 0;
+ /* Check the parameters */
+ assert_param(IS_PWR_ENTRY(PWR_Entry));
+
+ /* Select the regulator state in Sleep mode ---------------------------------*/
+ tmpreg = PWR->CR;
+ /* Clear LPDS bits */
+ tmpreg &= CR_DS_MASK;
+ /* Store the new value */
+ PWR->CR = tmpreg;
+
+ /* Select STOP mode entry --------------------------------------------------*/
+ if(PWR_Entry == PWR_Entry_WFI)
+ {
+ /* Request Wait For Interrupt */
+ __WFI();
+ }
+ else
+ {
+ /* Request Wait For Event */
+ __SEV();
+ __WFE();
+ __WFE();
+ }
+}
+
+
+/**
+ * @brief it will config LSI 128K as sysclk
+ * @retval None
+ * @note this fuction only used in fuction PWR_EnterDeepSleepMode(uint8_t PWR_Entry)
+ */
+static void Sysclk_SwitchToLSI(void)
+{
+ RCC_LSICmd(ENABLE);
+ while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);
+
+ /* Flash wait state */
+ FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
+ FLASH->ACR |= (uint32_t)FLASH_Latency_0;
+
+ /* Select LSI as system clock source */
+ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
+ RCC->CFGR |= (uint32_t)RCC_CFGR_SW_LSI;
+ /* Wait till LSI is used as system clock source */
+ while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != RCC_CFGR_SWS_LSI);
+
+ /* HCLK = SYSCLK */
+ RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
+
+ /* PCLK = HCLK */
+ RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE_DIV1;
+
+ // config the Flash Erase and program time
+ RCC->CFGR4 |= RCC_RCC_CFGR4_FLITFCLK_PRE;
+ RCC->CFGR4 &= ~(((uint32_t)0x0F) << RCC_RCC_CFGR4_FLITFCLK_PRE_Pos);
+
+ /* Close HSI */
+ RCC_HSICmd(DISABLE);
+
+}
+
+/**
+ * @brief Enters DeepSleep mode. it will config LSI 128K as sysclk
+ * @param PWR_Entry: specifies if Sleep mode in entered with WFI or WFE instruction.
+ * This parameter can be one of the following values:
+ * @arg PWR_Entry_WFI: enter Sleep mode with WFI instruction
+ * @arg PWR_Entry_WFE: enter Sleep mode with WFE instruction
+ * @retval None
+ */
+void PWR_EnterDeepSleepMode(uint8_t PWR_Entry)
+{
+ /* Check the parameters */
+ assert_param(IS_PWR_ENTRY(PWR_Entry));
+ /* set sysclk to LSI */
+ Sysclk_SwitchToLSI();
+ /* enter sleep mode */
+ PWR_EnterSleepMode(PWR_Entry);
+}
+
+
+/**
+ * @brief Enter Stop mode.
+ * @param PWR_Regulator: specifies the regulator state in STOP mode.
+ * This parameter can be one of the following values:
+ * @arg PWR_Regulator_LowPower: STOP mode with regulator in low power mode
+ * @param PWR_Entry: specifies if STOP mode in entered with WFI or WFE instruction.
+ * This parameter can be one of the following values:
+ * @arg PWR_Entry_WFI: enter STOP mode with WFI instruction
+ * @arg PWR_Entry_WFE: enter STOP mode with WFE instruction
+ * @retval None
+ */
+void PWR_EnterStopMode(uint32_t PWR_Regulator, uint8_t PWR_Entry)
+{
+ uint32_t tmpreg = 0;
+ /* Check the parameters */
+ assert_param(IS_PWR_REGULATOR(PWR_Regulator));
+ assert_param(IS_PWR_ENTRY(PWR_Entry));
+
+
+ /* Select the regulator state in Stop mode ---------------------------------*/
+ tmpreg = PWR->CR;
+ /* Clear LPDS bits */
+ tmpreg &= CR_DS_MASK;
+ /* Set LPDS bit according to PWR_Regulator value */
+ tmpreg |= PWR_Regulator;
+ /* Store the new value */
+ PWR->CR = tmpreg;
+ /* Set SLEEPDEEP bit of Cortex System Control Register */
+ SCB->SCR |= SCB_SCR_SLEEPDEEP;
+
+ /* Select Stop mode entry --------------------------------------------------*/
+ if(PWR_Entry == PWR_Entry_WFI)
+ {
+ /* Request Wait For Interrupt */
+ __WFI();
+ }
+ else
+ {
+ // wait the AWU is IDE and AWU_BUSY is 0
+ while(AWU->SR & 0x00000001){};
+
+ // detect and clear the AWU_EXTILINE11
+ if(EXTI_GetFlagStatus(EXTI_Line11) == SET)
+ {
+ EXTI_ClearFlag(EXTI_Line11);
+ }
+ /* Request Wait For Event */
+ __SEV();
+ __WFE();
+ __WFE();
+ }
+
+ /* Reset SLEEPDEEP bit of Cortex System Control Register */
+ SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP);
+}
+
+
+
+/**
+ * @brief Set PMU LDO Refernce voltage to adc.
+ * @param Vref_Set: internal Refernce out voltage ,
+ * This parameter can be: ADC_Vref_0d8 or ADC_Vref_LDO
+ ADC_Vref_0d8: 0.8V Vref to adc.
+ ADC_Vref_LDO: LDO out Voltage to adc .(1.2V)
+ * @retval None
+ */
+
+void PWR_SetLDO_RefVolToADC(uint16_t Vref_Set)
+{
+ uint16_t temp = 0;
+ /* Check the parameters */
+ assert_param(IS_PWR_VTEST_SET(Vref_Set));
+
+/* select the LDO Voltage reference register */
+ temp = PWR->VREF_SEL;
+
+ /* Clear LPDS bits */
+ temp &= VTEST_SET_MASK;
+
+ /* set the VREF*/
+ temp |= Vref_Set;
+
+ /* set the Register*/
+ PWR->VREF_SEL |= (uint32_t)temp;
+
+}
+
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_rcc.c b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_rcc.c
new file mode 100644
index 0000000..f4ad5f8
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_rcc.c
@@ -0,0 +1,1048 @@
+/**
+ ******************************************************************************
+ * @file hk32f030m_rcc.c
+ * @author Rakan.Z/laura.C
+ * @version V1.0
+ * @brief API file of rcc module
+ * @changelist
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "hk32f030m_rcc.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+
+/* ---------------------- RCC registers mask -------------------------------- */
+/* RCC Flag Mask */
+#define FLAG_MASK ((uint8_t)0x1F)
+
+/* CIR register byte 1 (Bits[15:8]) base address */
+#define CIR_BYTE1_ADDRESS ((uint32_t)0x40021009)
+
+/* CIR register byte 2 (Bits[23:16]) base address */
+#define CIR_BYTE2_ADDRESS ((uint32_t)0x4002100A)
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+const uint16_t AHBPrescTable[16] = {1, 6, 1, 1, 1, 1, 1, 1, 2, 4, 8, 16, 64, 128, 256, 512};
+const uint8_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4};
+
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+
+/** RCC_Group1 Internal and external clocks, PLL, CSS and MCO configuration functions
+ * brief Internal and external clocks, CSS and MCO configuration functions
+ *
+
+ ===============================================================================
+ ##### Internal-external clocks, PLL, CSS and MCO configuration functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to configure the internal/external clocks,
+ PLL, CSS and MCO.
+ (#) HSI (high-speed internal), 32 MHz factory-trimmed RC used directly .
+ The HSI clock can be used also to clock the USART, I2C peripherals.
+ (#) LSI (low-speed internal), 40 KHz low consumption RC used as IWDG clock source.
+ (#) EXT (high-speed external), 4 to 32 MHz used directly
+ (#) CSS (Clock security system), once enabled and if a EXT clock failure occurs,
+ the System clock is automatically switched to HSI and an interrupt is generated if enabled.
+ The interrupt is linked to the Cortex-M0 NMI (Non-Maskable Interrupt)
+ exception vector.
+ (#) MCO (microcontroller clock output), used to output SYSCLK, HSI, LSI, clock on PA8 pin.
+ */
+
+/**
+ * @brief Resets the RCC clock configuration to the default reset state.
+ * @note The default reset state of the clock configuration is given below:
+ * @note HSI ON and used as system clock source
+ * @note AHB, APB prescaler set to 1.
+ * @note MCO OFF
+ * @note All interrupts disabled
+ * @note However, this function doesn't modify the configuration of the
+ * @note Peripheral clocks
+ * @note LSI, RTC clocks
+ * @param None
+ * @retval None
+ */
+void RCC_DeInit(void)
+{
+ /* Set HSION bit */
+ RCC->CR |= (uint32_t)0x00000001;
+
+ /* Reset SW[1:0], HPRE[3:0], PPRE[2:0] and MCOSEL[2:0] bits */
+ RCC->CFGR &= (uint32_t)0xF8FFB81C;
+
+ /* Reset USARTSW[1:0], I2CSW bits */
+ RCC->CFGR3 &= (uint32_t)0xFFFFFFEC;
+
+ /* Disable all interrupts */
+ RCC->CIR = 0x00000000;
+}
+
+
+/**
+ * @brief Waits for start-up.
+ * @note This function waits on HSIRDY/LSIRDY/EXTRDY flag to be set and return SUCCESS if
+ * this flag is set, otherwise returns ERROR if the timeout is reached
+ * and this flag is not set. The timeout value is defined by the constant
+ * HSE_STARTUP_TIMEOUT in hk32f030m.h file. You can tailor it depending
+ * on the HSE crystal used in your application.
+ * @note is stopped by hardware when entering STOP modes.
+ * @param RCC_FLAG: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg RCC_FLAG_HSIRDY: HSI oscillator clock ready
+ * @arg RCC_FLAG_LSIRDY: LSI oscillator clock ready
+ * @arg RCC_FLAG_EXTRDY: EXT clock ready
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: HSE oscillator is stable and ready to use
+ * - ERROR: HSE oscillator not yet ready
+ */
+ErrorStatus RCC_WaitForStartUp(uint8_t RCC_FLAG)
+{
+ __IO uint32_t StartUpCounter = 0;
+ ErrorStatus status = ERROR;
+ FlagStatus HSEStatus = RESET;
+
+ /* Wait till HSE is ready and if timeout is reached exit */
+ do
+ {
+ HSEStatus = RCC_GetFlagStatus(RCC_FLAG);
+ StartUpCounter++;
+ } while((StartUpCounter != HSI_STARTUP_TIMEOUT) && (HSEStatus == RESET));
+
+ if(RCC_GetFlagStatus(RCC_FLAG) != RESET)
+ {
+ status = SUCCESS;
+ }
+ else
+ {
+ status = ERROR;
+ }
+ return (status);
+}
+
+/**
+ * @brief Adjusts 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 HSI calibration trimming value.
+ * This parameter must be a number between 0 and 0x1F.
+ * @retval None
+ */
+void RCC_AdjustHSICalibrationValue(uint8_t HSICalibrationValue)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_RCC_HSI_CALIBRATION_VALUE(HSICalibrationValue));
+
+ tmpreg = RCC->CR;
+
+ /* Clear HSITRIM[4:0] bits */
+ tmpreg &= ~RCC_CR_HSITRIM;
+
+ /* Set the HSITRIM[4:0] bits according to HSICalibrationValue value */
+ tmpreg |= (uint32_t)HSICalibrationValue << 3;
+
+ /* Store the new value */
+ RCC->CR = tmpreg;
+}
+
+/**
+ * @brief Enables or disables the Internal High Speed oscillator (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 to clock the PLL and/or system clock.
+ * @note HSI can not be stopped if it is used directly.
+ In this case, you have to select another source
+ * of the system clock then stop the HSI.
+ * @note The HSI is stopped by hardware when entering STOP modes.
+ * @param NewState: new state of the HSI.
+ * This parameter can be: ENABLE or DISABLE.
+ * @note When the HSI is stopped, HSIRDY flag goes low after 6 HSI oscillator
+ * clock cycles.
+ * @retval None
+ */
+void RCC_HSICmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ RCC->CR |= RCC_CR_HSION;
+ }
+ else
+ {
+ RCC->CR &= ~RCC_CR_HSION;
+ }
+}
+
+
+/**
+ * @brief Enables or disables 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.
+ * @note LSI can not be disabled if the IWDG is running.
+ * @param NewState: new state of the LSI.
+ * This parameter can be: ENABLE or DISABLE.
+ * @note When the LSI is stopped, LSIRDY flag goes low after 6 LSI oscillator
+ * clock cycles.
+ * @retval None
+ */
+void RCC_LSICmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ RCC->CSR |= RCC_CSR_LSION;
+ }
+ else
+ {
+ RCC->CSR &= ~RCC_CSR_LSION;
+ }
+}
+
+
+/**
+ * @brief Enables or disables the EXTCLK.
+ * @param NewState: new state of the LSI.
+ * This parameter can be: ENABLE or DISABLE.
+ * @param EXTCKL_SEL:
+ RCC_CFGR4_EXTCLK_SEL_PA1
+ RCC_CFGR4_EXTCLK_SEL_PD7
+ RCC_CFGR4_EXTCLK_SEL_PB5
+ RCC_CFGR4_EXTCLK_SEL_PC5
+ * @retval None
+ */
+void RCC_EXTCmd(FunctionalState NewState, uint32_t EXTCKL_SEL)
+{
+ //enable EXTIO PA1/PD71/PB5/PC5
+
+ /* Configure PA1 as CLOCK input */
+ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
+
+ GPIO_InitTypeDef GPIO_InitStructure;
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
+ GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
+ GPIO_Init(GPIOA, &GPIO_InitStructure);
+ /*CLOCK select */
+ RCC->CFGR4 &= (uint32_t)~(RCC_RCC_CFGR4_EXTCLK_SEL);
+ RCC->CFGR4 |= (uint32_t)EXTCKL_SEL;
+
+ if (NewState != DISABLE)
+ {
+ RCC->CR |= RCC_CR_EXTCLKON;
+ }
+ else
+ {
+ RCC->CR &= ~RCC_CR_EXTCLKON;
+ }
+}
+
+
+/**
+ * @brief Enables or disables the Clock Security System.
+ * @note If a failure is detected on the EXT clock, this CLK
+ * 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-M0 NMI (Non-Maskable Interrupt) exception vector.
+ * @param NewState: new state of the Clock Security System.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RCC_ClockSecuritySystemCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ RCC->CR |= RCC_CR_CSSON;
+ }
+ else
+ {
+ RCC->CR &= ~RCC_CR_CSSON;
+ }
+}
+
+
+
+/**
+ * @brief Selects the clock source to output on MCO pinx and the corresponding
+ * prescsaler.
+ * @note Pinx should be configured in alternate function mode.
+ * @param RCC_MCOSource: specifies the clock source to output.
+ * This parameter can be one of the following values:
+ * @arg RCC_MCOSource_NoClock: No clock selected.
+ * @arg RCC_MCOSource_LSI: LSI oscillator clock selected.
+ * @arg RCC_MCOSource_SYSCLK: System clock selected.
+ * @arg RCC_MCOSource_HSI: HSI oscillator clock selected.
+ * @param RCC_MCOPrescaler: specifies the prescaler on MCO pin.
+ * This parameter can be one of the following values:
+ * @arg RCC_MCOPrescaler_1: MCO clock is divided by 1.
+ * @arg RCC_MCOPrescaler_2: MCO clock is divided by 2.
+ * @arg RCC_MCOPrescaler_4: MCO clock is divided by 4.
+ * @arg RCC_MCOPrescaler_8: MCO clock is divided by 8.
+ * @arg RCC_MCOPrescaler_16: MCO clock is divided by 16.
+ * @arg RCC_MCOPrescaler_32: MCO clock is divided by 32.
+ * @arg RCC_MCOPrescaler_64: MCO clock is divided by 64.
+ * @arg RCC_MCOPrescaler_128: MCO clock is divided by 128.
+ * @retval None
+ */
+void RCC_MCOConfig(uint8_t RCC_MCOSource, uint32_t RCC_MCOPrescaler)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_RCC_MCO_SOURCE(RCC_MCOSource));
+ assert_param(IS_RCC_MCO_PRESCALER(RCC_MCOPrescaler));
+
+ /* Get CFGR value */
+ tmpreg = RCC->CFGR;
+ /* Clear MCOPRE[2:0] bits */
+ tmpreg &= ~(RCC_CFGR_MCO_PRE | RCC_CFGR_MCO );
+ /* Set the RCC_MCOSource and RCC_MCOPrescaler */
+ tmpreg |= (RCC_MCOPrescaler | ((uint32_t)RCC_MCOSource<<24));
+ /* Store the new value */
+ RCC->CFGR = tmpreg;
+}
+
+
+/** System AHB and APB busses clocks configuration functions
+ * brief System, AHB and APB busses clocks configuration functions
+ *
+ ===============================================================================
+ ##### System, AHB and APB busses clocks configuration functions #####
+ ===============================================================================
+
+ [..] This section provide functions allowing to configure the System, AHB and
+ APB busses clocks.
+ (#) Several clock sources can be used to drive the System clock (SYSCLK): HSI,
+ EXT and LSI.
+ 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 .
+ and APB (PCLK) clocks are derived from AHB clock through
+ configurable prescalers and used to clock the peripherals mapped on these busses.
+ You can use "RCC_GetClocksFreq()" function to retrieve the frequencies of these clocks.
+
+ -@- All the peripheral clocks are derived from the System clock (SYSCLK) except:
+ (+@) The ADC clock which is derived from HSI14 or APB (APB divided by a
+ programmable prescaler: 2 or 4).
+ (+@) The I2C clock which is derived from HSI or system clock (SYSCLK).
+ (+@) The USART clock which is derived from HSI, system clock (SYSCLK), APB or LSE.
+ (+@) IWDG clock which is always the LSI clock.
+
+ (#) The maximum frequency of the SYSCLK, HCLK and PCLK is 32 MHz.
+ Depending on the maximum frequency, the FLASH wait states (WS) should be
+ adapted accordingly:
+ +--------------------------------------------- +
+ | Wait states | HCLK clock frequency (MHz) |
+ |---------------|------------------------------|
+ |0WS(1CPU cycle)| 0 < HCLK <= 24 |
+ |---------------|------------------------------|
+ |1WS(2CPU cycle)| 24 < HCLK <= 32 |
+ +----------------------------------------------+
+
+ (#) After reset, the System clock source is the HSI (32 MHz)/6 with 0 WS and
+ prefetch is disabled.
+
+ [..] It is recommended to use the following software sequences to tune the number
+ of wait states needed to access the Flash memory with the CPU frequency (HCLK).
+ (+) Increasing the CPU frequency
+ (++) Program Flash WS to 1, using "FLASH_SetLatency(FLASH_Latency_1)" function
+ (++) Check that the new number of WS is taken into account by reading FLASH_ACR
+ (++) Modify the CPU clock source, using "RCC_SYSCLKConfig()" function
+ (++) If needed, modify the CPU clock prescaler by using "RCC_HCLKConfig()" function
+ (++) Check that the new CPU clock source is taken into account by reading
+ the clock source status, using "RCC_GetSYSCLKSource()" function
+ (+) Decreasing the CPU frequency
+ (++) Modify the CPU clock source, using "RCC_SYSCLKConfig()" function
+ (++) If needed, modify the CPU clock prescaler by using "RCC_HCLKConfig()" function
+ (++) Check that the new CPU clock source is taken into account by reading
+ the clock source status, using "RCC_GetSYSCLKSource()" function
+ (++) Program the new number of WS, using "FLASH_SetLatency()" function
+ (++) Check that the new number of WS is taken into account by reading FLASH_ACR
+ (++) Disable the Flash Prefetch buffer using "FLASH_PrefetchBufferCmd(DISABLE)"
+ function
+ (++) Check that Flash Prefetch buffer deactivation is taken into account by reading FLASH_ACR
+ using the FLASH_GetPrefetchBufferStatus() function.
+ */
+
+/**
+ * @brief Configures the system clock (SYSCLK).
+ * @note The HSI is used (enabled by hardware) as system clock source after
+ * startup from Reset, wake-up from STOP mode.
+ * @note A switch from one clock source to another occurs only if the target
+ * clock source is ready (clock stable after startup 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 RCC_GetSYSCLKSource() function to know which clock is
+ * currently used as system clock source.
+ * @param RCC_SYSCLKSource: specifies the clock source used as system clock source
+ * This parameter can be one of the following values:
+ * @arg RCC_SYSCLKSource_HSI: HSI selected as system clock source
+ * @arg RCC_SYSCLKSource_EXTCLK: EXTCLK selected as system clock source
+ * @arg RCC_SYSCLKSource_LSI: LSI selected as system clock source
+ * @retval None
+ */
+void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_RCC_SYSCLK_SOURCE(RCC_SYSCLKSource));
+
+ tmpreg = RCC->CFGR;
+
+ /* Clear SW[1:0] bits */
+ tmpreg &= ~RCC_CFGR_SW;
+
+ /* Set SW[1:0] bits according to RCC_SYSCLKSource value */
+ tmpreg |= RCC_SYSCLKSource;
+
+ /* Store the new value */
+ RCC->CFGR = tmpreg;
+}
+
+/**
+ * @brief Returns the clock source used as system clock.
+ * @param None
+ * @retval The clock source used as system clock. The returned value can be one
+ * of the following values:
+ * - 0x00: HSI used as system clock
+ * - 0x04: EXTCLK used as system clock
+ * - 0x0C: LSI used as system clock
+ */
+uint8_t RCC_GetSYSCLKSource(void)
+{
+ return ((uint8_t)(RCC->CFGR & RCC_CFGR_SWS));
+}
+
+/**
+ * @brief Configures the AHB clock (HCLK).
+ * @param RCC_SYSCLK: defines the AHB clock divider. This clock is derived from
+ * the system clock (SYSCLK).
+ * This parameter can be one of the following values:
+ * @arg RCC_SYSCLK_Div1: AHB clock = SYSCLK
+ * @arg RCC_SYSCLK_Div2: AHB clock = SYSCLK/2
+ * @arg RCC_SYSCLK_Div4: AHB clock = SYSCLK/4
+ * @arg RCC_SYSCLK_Div6: AHB clock = SYSCLK/6
+ * @arg RCC_SYSCLK_Div8: AHB clock = SYSCLK/8
+ * @arg RCC_SYSCLK_Div16: AHB clock = SYSCLK/16
+ * @arg RCC_SYSCLK_Div64: AHB clock = SYSCLK/64
+ * @arg RCC_SYSCLK_Div128: AHB clock = SYSCLK/128
+ * @arg RCC_SYSCLK_Div256: AHB clock = SYSCLK/256
+ * @arg RCC_SYSCLK_Div512: AHB clock = SYSCLK/512
+ * @retval None
+ */
+void RCC_HCLKConfig(uint32_t RCC_SYSCLK)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_RCC_HCLK(RCC_SYSCLK));
+
+ tmpreg = RCC->CFGR;
+
+ /* Clear HPRE[3:0] bits */
+ tmpreg &= ~RCC_CFGR_HPRE;
+
+ /* Set HPRE[3:0] bits according to RCC_SYSCLK value */
+ tmpreg |= RCC_SYSCLK;
+
+ /* Store the new value */
+ RCC->CFGR = tmpreg;
+}
+
+/**
+ * @brief Configures the APB clock (PCLK).
+ * @param RCC_HCLK: defines the APB clock divider. This clock is derived from
+ * the AHB clock (HCLK).
+ * This parameter can be one of the following values:
+ * @arg RCC_HCLK_Div1: APB clock = HCLK
+ * @arg RCC_HCLK_Div2: APB clock = HCLK/2
+ * @arg RCC_HCLK_Div4: APB clock = HCLK/4
+ * @arg RCC_HCLK_Div8: APB clock = HCLK/8
+ * @arg RCC_HCLK_Div16: APB clock = HCLK/16
+ * @retval None
+ */
+void RCC_PCLKConfig(uint32_t RCC_HCLK)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_RCC_PCLK(RCC_HCLK));
+
+ tmpreg = RCC->CFGR;
+
+ /* Clear PPRE[2:0] bits */
+ tmpreg &= ~RCC_CFGR_PPRE;
+
+ /* Set PPRE[2:0] bits according to RCC_HCLK value */
+ tmpreg |= RCC_HCLK;
+
+ /* Store the new value */
+ RCC->CFGR = tmpreg;
+}
+
+/**
+ * @brief Configures the ADC clock (ADCCLK).
+ * @param RCC_ADCCLK: defines the ADC clock source. This clock is derived
+ * from the HSI14 or APB clock (PCLK).
+ * This parameter can be one of the following values:
+ * @arg RCC_ADCCLK_HSI32M_Div1:
+ * @arg RCC_ADCCLK_HSI32M_Div1_5
+
+ * @arg RCC_ADCCLK_HSI32M_Div16_5
+ * @arg RCC_ADCCLK_PCLK_DIV2
+ * @arg RCC_ADCCLK_PCLK_DIV4
+ * @retval None
+ */
+void RCC_ADCCLKConfig(uint32_t RCC_ADCCLK)
+{
+ ADC1->CFGR2&= ~ADC_CFGR2_CKMODE;
+
+ if((RCC_ADCCLK==RCC_ADCCLK_PCLK_DIV2)||(RCC_ADCCLK==RCC_ADCCLK_PCLK_DIV4))
+ {
+ ADC1->CFGR2|=RCC_ADCCLK;
+ }
+ else
+ {
+ /* Clear ADCPRE bit */
+ RCC->CFGR4 &= ~RCC_CFGR4_ADCHSIPRE;
+ /* Set ADCPRE bits according to RCC_PCLK value */
+ RCC->CFGR4 |= (RCC_ADCCLK & RCC_CFGR4_ADCHSIPRE);
+ }
+}
+
+
+/**
+ * @brief Configures the I2C1 clock (I2C1CLK).
+ * @param RCC_I2CCLK: defines the I2C1 clock source. This clock is derived
+ * from the HSI or System clock.
+ * This parameter can be one of the following values:
+ * @arg RCC_I2C1CLK_HSI: I2C1 clock = HSI
+ * @arg RCC_I2C1CLK_SYSCLK: I2C1 clock = System Clock
+ * @retval None
+ */
+void RCC_I2CCLKConfig(uint32_t RCC_I2CCLK)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_I2CCLK(RCC_I2CCLK));
+
+ /* Clear I2CSW bit */
+ RCC->CFGR3 &= ~RCC_CFGR3_I2C1SW;
+ /* Set I2CSW bits according to RCC_I2CCLK value */
+ RCC->CFGR3 |= RCC_I2CCLK;
+}
+
+/**
+ * @brief Configures the USART1 clock (USART1CLK).
+ * @param RCC_USARTCLK: defines the USART clock source. This clock is derived
+ * from the HSI or System clock.
+ * This parameter can be one of the following values:
+ * @arg RCC_USART1CLK_PCLK: USART1 clock = APB Clock (PCLK)
+ * @arg RCC_USART1CLK_SYSCLK: USART1 clock = System Clock
+ * @arg RCC_USART1CLK_HSI: USART1 clock = HSI Clock
+ * @retval None
+ */
+void RCC_USARTCLKConfig(uint32_t RCC_USARTCLK)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_USARTCLK(RCC_USARTCLK));
+
+ /* Clear USART1SW[1:0] bit */
+ RCC->CFGR3 &= ~RCC_CFGR3_USART1SW;
+
+ /* Set USARTxSW bits according to RCC_USARTCLK value */
+ RCC->CFGR3 |= RCC_USARTCLK;
+}
+
+
+/**
+ * @brief Returns the frequencies of the System, AHB and APB busses clocks.
+ * @note The frequency returned by this function is not the real frequency
+ * in the chip. It is calculated based on the predefined constant and
+ * the source selected by RCC_SYSCLKConfig():
+ *
+ * @note The result of this function could be not correct when using fractional
+ * value for HSE crystal.
+ *
+ * @param RCC_Clocks: pointer to a RCC_ClocksTypeDef structure which will hold
+ * the clocks frequencies.
+ *
+ * @note This function can be used by the user application to compute the
+ * baudrate for the communication peripherals or configure other parameters.
+ * @note Each time SYSCLK, HCLK and/or PCLK clock changes, this function
+ * must be called to update the structure's field. Otherwise, any
+ * configuration based on this function will be incorrect.
+ *
+ * @retval None
+ */
+void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks)
+{
+ uint32_t tmp = 0, presc = 0;
+
+ /* Get SYSCLK source -------------------------------------------------------*/
+ tmp = RCC->CFGR & RCC_CFGR_SWS;
+
+ switch (tmp)
+ {
+ case 0x00: /* HSI used as system clock */
+ RCC_Clocks->SYSCLK_Frequency = HSI_VALUE;
+ break;
+
+ case 0x04: /* EXTCLK used as system clock */
+ RCC_Clocks->SYSCLK_Frequency = EXTCLK_VALUE;
+ break;
+
+ case 0x0C: /* LSI used as system clock */
+ RCC_Clocks->SYSCLK_Frequency = LSI_VALUE;
+
+ default: /* HSI used as system clock */
+ RCC_Clocks->SYSCLK_Frequency = HSI_VALUE;
+ break;
+ }
+ /* Compute HCLK, PCLK clocks frequencies -----------------------------------*/
+ /* Get HCLK prescaler */
+ tmp = RCC->CFGR & RCC_CFGR_HPRE;
+ tmp = tmp >> 4;
+ presc = AHBPrescTable[tmp];
+ /* HCLK clock frequency */
+ RCC_Clocks->HCLK_Frequency = RCC_Clocks->SYSCLK_Frequency/presc;
+
+ /* Get PCLK prescaler */
+ tmp = RCC->CFGR & RCC_CFGR_PPRE;
+ tmp = tmp >> 8;
+ presc = APBPrescTable[tmp];
+ /* PCLK clock frequency */
+ RCC_Clocks->PCLK_Frequency = RCC_Clocks->HCLK_Frequency >> presc;
+
+ /* ADCCLK clock frequency */
+ if((ADC1->CFGR2 & ADC_CFGR2_CKMODE) == 0x0)
+ {
+ /* ADC Clock is HSI Osc. */
+ tmp = RCC->CFGR4 & RCC_CFGR4_ADCHSIPRE;
+ tmp = tmp >> 26;
+ RCC_Clocks->ADCCLK_Frequency = (HSI_VALUE<<1)/(tmp+2);
+ }
+ else if((ADC1->CFGR2 & ADC_CFGR2_CKMODE) != ADC_CFGR2_CKMODE_0)
+ {
+ /* ADC Clock is derived from PCLK/2 */
+ RCC_Clocks->ADCCLK_Frequency = RCC_Clocks->PCLK_Frequency >> 1;
+ }
+ else if((ADC1->CFGR2 & ADC_CFGR2_CKMODE) != ADC_CFGR2_CKMODE_1)
+ {
+ /* ADC Clock is derived from PCLK/4 */
+ RCC_Clocks->ADCCLK_Frequency = RCC_Clocks->PCLK_Frequency >> 2;
+ }
+
+ /* I2C1CLK clock frequency */
+ if((RCC->CFGR3 & RCC_CFGR3_I2C1SW) != RCC_CFGR3_I2C1SW)
+ {
+ /* I2C1 Clock is HSI Osc. */
+ RCC_Clocks->I2C1CLK_Frequency = HSI_VALUE;
+ }
+ else
+ {
+ /* I2C1 Clock is System Clock */
+ RCC_Clocks->I2C1CLK_Frequency = RCC_Clocks->SYSCLK_Frequency;
+ }
+
+ /* USART1CLK clock frequency */
+ if((RCC->CFGR3 & RCC_CFGR3_USART1SW) == 0x0)
+ {
+ /* USART1 Clock is PCLK */
+ RCC_Clocks->USART1CLK_Frequency = RCC_Clocks->PCLK_Frequency;
+ }
+ else if((RCC->CFGR3 & RCC_CFGR3_USART1SW) == RCC_CFGR3_USART1SW_0)
+ {
+ /* USART1 Clock is System Clock */
+ RCC_Clocks->USART1CLK_Frequency = RCC_Clocks->SYSCLK_Frequency;
+ }
+ else if((RCC->CFGR3 & RCC_CFGR3_USART1SW) == RCC_CFGR3_USART1SW)
+ {
+ /* USART1 Clock is HSI Osc. */
+ RCC_Clocks->USART1CLK_Frequency = HSI_VALUE;
+ }
+
+}
+
+
+/** RCC_Group3 Peripheral clocks configuration functions
+ * Peripheral clocks configuration functions
+ *
+ ===============================================================================
+ #####Peripheral clocks configuration functions #####
+ ===============================================================================
+
+ [..] This section provide functions allowing to configure the Peripheral clocks.
+ (#) After restart from Reset , all peripherals are off
+ except internal SRAM, Flash and SWD. Before to start using a peripheral you
+ have to enable its interface clock. You can do this using RCC_AHBPeriphClockCmd(),
+ RCC_APB2PeriphClockCmd() and RCC_APB1PeriphClockCmd() functions.
+ (#) To reset the peripherals configuration (to the default state after device reset)
+ you can use RCC_AHBPeriphResetCmd(), RCC_APB2PeriphResetCmd() and
+ RCC_APB1PeriphResetCmd() functions.
+ */
+
+/**
+ * @brief Enables or disables 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.
+ * @param RCC_AHBPeriph: specifies the AHB peripheral to gates its clock.
+ * This parameter can be any combination of the following values:
+ * @arg RCC_AHBPeriph_GPIOA: GPIOA clock
+ * @arg RCC_AHBPeriph_GPIOB: GPIOB clock
+ * @arg RCC_AHBPeriph_GPIOC: GPIOC clock
+ * @arg RCC_AHBPeriph_GPIOD: GPIOD clock
+ * @arg RCC_AHBPeriph_CRC: CRC clock
+ * @arg RCC_AHBPeriph_FLITF: (has effect only when the Flash memory is in power down mode)
+ * @arg RCC_AHBPeriph_SRAM: SRAM clock
+ * @param NewState: new state of the specified peripheral clock.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_AHB_PERIPH(RCC_AHBPeriph));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ RCC->AHBENR |= RCC_AHBPeriph;
+ }
+ else
+ {
+ RCC->AHBENR &= ~RCC_AHBPeriph;
+ }
+}
+
+/**
+ * @brief Enables or disables 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.
+ * @param RCC_APB2Periph: specifies the APB2 peripheral to gates its clock.
+ * This parameter can be any combination of the following values:
+ * @arg RCC_APB2Periph_SYSCFG: SYSCFG clock
+ * @arg RCC_APB2Periph_ADC: ADC clock
+ * @arg RCC_APB2Periph_TIM1: TIM1 clock
+ * @arg RCC_APB2Periph_SPI1: SPI1 clock
+ * @arg RCC_APB2Periph_USART1: USART1 clock
+ * @arg RCC_APB2Periph_DBGMCU: DBGMCU clock
+ * @param NewState: new state of the specified peripheral clock.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ RCC->APB2ENR |= RCC_APB2Periph;
+ }
+ else
+ {
+ RCC->APB2ENR &= ~RCC_APB2Periph;
+ }
+}
+
+/**
+ * @brief Enables or disables 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.
+ * @param RCC_APB1Periph: specifies the APB1 peripheral to gates its clock.
+ * This parameter can be any combination of the following values:
+ * @arg RCC_APB1Periph_TIM2: TIM2 clock
+ * @arg RCC_APB1Periph_TIM6: TIM6 clock
+ * @arg RCC_APB1Periph_WWDG: WWDG clock
+ * @arg RCC_APB1Periph_AWU: AWU clock
+ * @arg RCC_APB1Periph_I2C1: I2C1 clock
+ * @arg RCC_APB1Periph_PWR: PWR clock
+ * @arg RCC_APB1Periph_BEEPER: BEEPER clock
+ * @arg RCC_APB1Periph_IOMUX: IOMUX clock
+ * @param NewState: new state of the specified peripheral clock.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_APB1_PERIPH(RCC_APB1Periph));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ RCC->APB1ENR |= RCC_APB1Periph;
+ }
+ else
+ {
+ RCC->APB1ENR &= ~RCC_APB1Periph;
+ }
+}
+
+/**
+ * @brief Forces or releases AHB peripheral reset.
+ * @param RCC_AHBPeriph: specifies the AHB peripheral to reset.
+ * This parameter can be any combination of the following values:
+ * @arg RCC_AHBRSTR_GPIOARST: GPIOA clock
+ * @arg RCC_AHBRSTR_GPIOBRST: GPIOB clock
+ * @arg RCC_AHBRSTR_GPIOCRST: GPIOC clock
+ * @arg RCC_AHBRSTR_GPIODRST: GPIOD clock
+ * @arg RCC_AHBRSTR_CRCRST: CRC clock
+ * @param NewState: new state of the specified peripheral reset.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RCC_AHBPeriphResetCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_AHB_RST_PERIPH(RCC_AHBPeriph));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ RCC->AHBRSTR |= RCC_AHBPeriph;
+ }
+ else
+ {
+ RCC->AHBRSTR &= ~RCC_AHBPeriph;
+ }
+}
+
+/**
+ * @brief Forces or releases High Speed APB (APB2) peripheral reset.
+ * @param RCC_APB2Periph: specifies the APB2 peripheral to reset.
+ * This parameter can be any combination of the following values:
+ * @arg RCC_APB2Periph_SYSCFG: SYSCFG clock
+ * @arg RCC_APB2Periph_ADC: ADC clock
+ * @arg RCC_APB2Periph_TIM1: TIM1 clock
+ * @arg RCC_APB2Periph_SPI1: SPI1 clock
+ * @arg RCC_APB2Periph_USART1: USART1 clock
+ * @arg RCC_APB2Periph_DBGMCU: DBGMCU clock
+
+ * @param NewState: new state of the specified peripheral reset.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ RCC->APB2RSTR |= RCC_APB2Periph;
+ }
+ else
+ {
+ RCC->APB2RSTR &= ~RCC_APB2Periph;
+ }
+}
+
+/**
+ * @brief Forces or releases Low Speed APB (APB1) peripheral reset.
+ * @param RCC_APB1Periph: specifies the APB1 peripheral to reset.
+ * This parameter can be any combination of the following values:
+ * @arg RCC_APB1Periph_TIM2: TIM2 clock
+ * @arg RCC_APB1Periph_TIM6: TIM6 clock
+ * @arg RCC_APB1Periph_WWDG: WWDG clock
+ * @arg RCC_APB1Periph_AWU: AWU clock
+ * @arg RCC_APB1Periph_I2C1: I2C1 clock
+ * @arg RCC_APB1Periph_PWR: PWR clock
+ * @arg RCC_APB1Periph_BEEPER: BEEPER clock
+ * @arg RCC_APB1Periph_IOMUX: IOMUX clock
+ * @param NewState: new state of the specified peripheral clock.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_APB1_PERIPH(RCC_APB1Periph));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ RCC->APB1RSTR |= RCC_APB1Periph;
+ }
+ else
+ {
+ RCC->APB1RSTR &= ~RCC_APB1Periph;
+ }
+}
+
+/** RCC_Group4 Interrupts and flags management functions
+ * Interrupts and flags management functions
+ *
+
+ ===============================================================================
+ ##### Interrupts and flags management functions #####
+ ===============================================================================
+ */
+
+/**
+ * @brief Enables or disables the specified RCC interrupts.
+ * @note The CSS interrupt doesn't have an enable bit; once the CSS is enabled
+ * and if the HSE clock fails, the CSS interrupt occurs and an NMI is
+ * automatically generated. The NMI will be executed indefinitely, and
+ * since NMI has higher priority than any other IRQ (and main program)
+ * the application will be stacked in the NMI ISR unless the CSS interrupt
+ * pending bit is cleared.
+ * @param RCC_IT: specifies the RCC interrupt sources to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * @arg RCC_IT_LSIRDY: LSI ready interrupt
+ * @arg RCC_IT_HSIRDY: HSI ready interrupt
+ * @arg RCC_IT_EXTRDY: EXT ready interrupt
+ * @arg RCC_IT_CSS: CSS interrupt
+ * @param NewState: new state of the specified RCC interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RCC_ITConfig(uint8_t RCC_IT, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Perform Byte access to RCC_CIR[13:8] bits to enable the selected interrupts */
+ *(__IO uint8_t *) CIR_BYTE1_ADDRESS |= RCC_IT;
+ }
+ else
+ {
+ /* Perform Byte access to RCC_CIR[13:8] bits to disable the selected interrupts */
+ *(__IO uint8_t *) CIR_BYTE1_ADDRESS &= (uint8_t)~RCC_IT;
+ }
+}
+
+/**
+ * @brief Checks whether the specified RCC flag is set or not.
+ * @param RCC_FLAG: specifies the flag to check.
+ * This parameter can be one of the following values:
+ RCC_FLAG_HSIRDY
+ RCC_FLAG_PINRST
+ RCC_FLAG_PORRST
+ RCC_FLAG_SFTRST
+ RCC_FLAG_IWDGRST
+ RCC_FLAG_WWDGRST
+ RCC_FLAG_LPWRRST
+ * @retval The new state of RCC_FLAG (SET or RESET).
+ */
+FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG)
+{
+ uint32_t tmp = 0;
+ uint32_t statusreg = 0;
+ FlagStatus bitstatus = RESET;
+
+ /* Check the parameters */
+ assert_param(IS_RCC_FLAG(RCC_FLAG));
+
+ /* Get the RCC register index */
+ tmp = RCC_FLAG >> 5;
+
+ if (tmp == 1) /* The flag to check is in CR register */
+ {
+ statusreg = RCC->CR;
+ }
+ else if (tmp == 3) /* The flag to check is in CSR register */
+ {
+ statusreg = RCC->CSR;
+ }
+
+ /* Get the flag position */
+ tmp = RCC_FLAG & FLAG_MASK;
+
+ if ((statusreg & ((uint32_t)1 << tmp)) != (uint32_t)RESET)
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+ /* Return the flag status */
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the RCC reset flags.
+ * The reset flags are: RCC_FLAG_OBLRST, RCC_FLAG_PINRST, RCC_FLAG_V18PWRRSTF,
+ * RCC_FLAG_PORRST, RCC_FLAG_SFTRST, RCC_FLAG_IWDGRST, RCC_FLAG_WWDGRST,
+ * RCC_FLAG_LPWRRST.
+ * @param None
+ * @retval None
+ */
+void RCC_ClearFlag(void)
+{
+ /* Set RMVF bit to clear the reset flags */
+ RCC->CSR |= RCC_CSR_RMVF;
+}
+
+/**
+ * @brief Checks whether the specified RCC interrupt has occurred or not.
+ * @param RCC_IT: specifies the RCC interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg RCC_IT_LSIRDY: LSI ready interrupt
+ * @arg RCC_IT_HSIRDY: HSI ready interrupt
+ * @arg RCC_IT_EXTRDY: EXT ready interrupt
+ * @arg RCC_IT_CSS: CSS interrupt
+ * @retval The new state of RCC_IT (SET or RESET).
+ */
+ITStatus RCC_GetITStatus(uint8_t RCC_IT)
+{
+ ITStatus bitstatus = RESET;
+
+ /* Check the parameters */
+ assert_param(IS_RCC_GET_IT(RCC_IT));
+
+ /* Check the status of the specified RCC interrupt */
+ if ((RCC->CIR & RCC_IT) != (uint32_t)RESET)
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+ /* Return the RCC_IT status */
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the RCC's interrupt pending bits.
+ * @param RCC_IT: specifies the interrupt pending bit to clear.
+ * This parameter can be any combination of the following values:
+ * @arg RCC_IT_LSIRDY: LSI ready interrupt
+ * @arg RCC_IT_HSIRDY: HSI ready interrupt
+ * @arg RCC_IT_EXTRDY: EXT ready interrupt
+ * @arg RCC_IT_CSS: CSS interrupt
+ * @retval None
+ */
+void RCC_ClearITPendingBit(uint8_t RCC_IT)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_CLEAR_IT(RCC_IT));
+
+ /* Perform Byte access to RCC_CIR[23:16] bits to clear the selected interrupt
+ pending bits */
+ *(__IO uint8_t *) CIR_BYTE2_ADDRESS = RCC_IT;
+}
+
+
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_spi.c b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_spi.c
new file mode 100644
index 0000000..79b11c1
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_spi.c
@@ -0,0 +1,1113 @@
+/**
+ ******************************************************************************
+ * @file hk32f030m_spi.c
+ * @version V1.0.1
+ * @date 2019-12-16
+ * @author Rakan.Z/wing.Wang
+ ===============================================================================
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "hk32f030m_spi.h"
+#include "hk32f030m_rcc.h"
+
+/** @defgroup SPI
+ * @brief SPI driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* SPI registers Masks */
+#define CR1_CLEAR_MASK ((uint16_t)0x3040)
+#define CR1_CLEAR_MASK2 ((uint16_t)0xFFFB)
+#define CR2_LDMA_MASK ((uint16_t)0x9FFF)
+
+#define I2SCFGR_CLEAR_Mask ((uint16_t)0xF040)
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup SPI_Private_Functions
+ * @{
+ */
+
+/** @defgroup SPI_Group1 Initialization and Configuration functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Initialization and Configuration functions #####
+ ===============================================================================
+ [..] This section provides a set of functions allowing to initialize the SPI Direction,
+ SPI Mode, SPI Data Size, SPI Polarity, SPI Phase, SPI NSS Management, SPI Baud
+ Rate Prescaler, SPI First Bit and SPI CRC Polynomial.
+
+ [..] The SPI_Init() function follows the SPI configuration procedures for Master mode
+ and Slave mode (details for these procedures are available in reference manual).
+
+ [..] When the Software NSS management (SPI_InitStruct->SPI_NSS = SPI_NSS_Soft) is selected,
+ use the following function to manage the NSS bit:
+ void SPI_NSSInternalSoftwareConfig(SPI_TypeDef* SPIx, uint16_t SPI_NSSInternalSoft);
+
+ [..] In Master mode, when the Hardware NSS management (SPI_InitStruct->SPI_NSS = SPI_NSS_Hard)
+ is selected, use the follwoing function to enable the NSS output feature.
+ void SPI_SSOutputCmd(SPI_TypeDef* SPIx, FunctionalState NewState);
+
+ [..] The NSS pulse mode can be managed by the SPI TI mode when enabling it using the following function:
+ void SPI_TIModeCmd(SPI_TypeDef* SPIx, FunctionalState NewState);
+ And it can be managed by software in the SPI Motorola mode using this function:
+ void SPI_NSSPulseModeCmd(SPI_TypeDef* SPIx, FunctionalState NewState);
+
+ [..] This section provides also functions to initialize the I2S Mode, Standard,
+ Data Format, MCLK Output, Audio frequency and Polarity.
+
+ [..] The I2S_Init() function follows the I2S configuration procedures for Master mode
+ and Slave mode.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Deinitializes the SPIx peripheral registers to their default
+ * reset values.
+ * @param SPIx: where x can be 1 to select the SPI peripheral.
+ * @retval None
+ */
+void SPI_I2S_DeInit(SPI_TypeDef* SPIx)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+
+ if (SPIx == SPI1)
+ {
+ /* Enable SPI1 reset state */
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, ENABLE);
+ /* Release SPI1 from reset state */
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, DISABLE);
+ }
+}
+
+/**
+ * @brief Fills each SPI_InitStruct member with its default value.
+ * @param SPI_InitStruct: pointer to a SPI_InitTypeDef structure which will be initialized.
+ * @retval None
+ */
+void SPI_StructInit(SPI_InitTypeDef* SPI_InitStruct)
+{
+/*--------------- Reset SPI init structure parameters values -----------------*/
+ /* Initialize the SPI_Direction member */
+ SPI_InitStruct->SPI_Direction = SPI_Direction_2Lines_FullDuplex;
+ /* Initialize the SPI_Mode member */
+ SPI_InitStruct->SPI_Mode = SPI_Mode_Slave;
+ /* Initialize the SPI_DataSize member */
+ SPI_InitStruct->SPI_DataSize = SPI_DataSize_8b;
+ /* Initialize the SPI_CPOL member */
+ SPI_InitStruct->SPI_CPOL = SPI_CPOL_Low;
+ /* Initialize the SPI_CPHA member */
+ SPI_InitStruct->SPI_CPHA = SPI_CPHA_1Edge;
+ /* Initialize the SPI_NSS member */
+ SPI_InitStruct->SPI_NSS = SPI_NSS_Hard;
+ /* Initialize the SPI_BaudRatePrescaler member */
+ SPI_InitStruct->SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
+ /* Initialize the SPI_FirstBit member */
+ SPI_InitStruct->SPI_FirstBit = SPI_FirstBit_MSB;
+ /* Initialize the SPI_CRCPolynomial member */
+ SPI_InitStruct->SPI_CRCPolynomial = 7;
+}
+
+/**
+ * @brief Initializes the SPIx peripheral according to the specified
+ * parameters in the SPI_InitStruct.
+ * @param SPIx: where x can be 1 to select the SPI peripheral.
+ * @param SPI_InitStruct: pointer to a SPI_InitTypeDef structure that
+ * contains the configuration information for the specified SPI peripheral.
+ * @retval None
+ */
+void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct)
+{
+ uint16_t tmpreg = 0;
+
+ /* check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+
+ /* Check the SPI parameters */
+ assert_param(IS_SPI_DIRECTION_MODE(SPI_InitStruct->SPI_Direction));
+ assert_param(IS_SPI_MODE(SPI_InitStruct->SPI_Mode));
+ assert_param(IS_SPI_DATA_SIZE(SPI_InitStruct->SPI_DataSize));
+ assert_param(IS_SPI_CPOL(SPI_InitStruct->SPI_CPOL));
+ assert_param(IS_SPI_CPHA(SPI_InitStruct->SPI_CPHA));
+ assert_param(IS_SPI_NSS(SPI_InitStruct->SPI_NSS));
+ assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_InitStruct->SPI_BaudRatePrescaler));
+ assert_param(IS_SPI_FIRST_BIT(SPI_InitStruct->SPI_FirstBit));
+ assert_param(IS_SPI_CRC_POLYNOMIAL(SPI_InitStruct->SPI_CRCPolynomial));
+
+ /*---------------------------- SPIx CR1 Configuration ------------------------*/
+ /* Get the SPIx CR1 value */
+ tmpreg = SPIx->CR1;
+ /* Clear BIDIMode, BIDIOE, RxONLY, SSM, SSI, LSBFirst, BR, CPOL and CPHA bits */
+ tmpreg &= CR1_CLEAR_MASK;
+ /* Configure SPIx: direction, NSS management, first transmitted bit, BaudRate prescaler
+ master/slave mode, CPOL and CPHA */
+ /* Set BIDImode, BIDIOE and RxONLY bits according to SPI_Direction value */
+ /* Set SSM, SSI bit according to SPI_NSS values */
+ /* Set LSBFirst bit according to SPI_FirstBit value */
+ /* Set BR bits according to SPI_BaudRatePrescaler value */
+ /* Set CPOL bit according to SPI_CPOL value */
+ /* Set CPHA bit according to SPI_CPHA value */
+ tmpreg |= (uint16_t)((uint32_t)SPI_InitStruct->SPI_Direction | SPI_InitStruct->SPI_FirstBit |
+ SPI_InitStruct->SPI_CPOL | SPI_InitStruct->SPI_CPHA |
+ SPI_InitStruct->SPI_NSS | SPI_InitStruct->SPI_BaudRatePrescaler);
+ /* Write to SPIx CR1 */
+ SPIx->CR1 = tmpreg;
+ /*-------------------------Data Size Configuration -----------------------*/
+ /* Get the SPIx CR2 value */
+ tmpreg = SPIx->CR2;
+ /* Clear DS[3:0] bits */
+ tmpreg &=(uint16_t)~SPI_CR2_DS;
+ /* Configure SPIx: Data Size */
+ tmpreg |= (uint16_t)(SPI_InitStruct->SPI_DataSize);
+ /* Write to SPIx CR2 */
+ SPIx->CR2 = tmpreg;
+
+ /*---------------------------- SPIx CRCPOLY Configuration --------------------*/
+ /* Write to SPIx CRCPOLY */
+ SPIx->CRCPR = SPI_InitStruct->SPI_CRCPolynomial;
+
+ /*---------------------------- SPIx CR1 Configuration ------------------------*/
+ /* Get the SPIx CR1 value */
+ tmpreg = SPIx->CR1;
+ /* Clear MSTR bit */
+ tmpreg &= CR1_CLEAR_MASK2;
+ /* Configure SPIx: master/slave mode */
+ /* Set MSTR bit according to SPI_Mode */
+ tmpreg |= (uint16_t)((uint32_t)SPI_InitStruct->SPI_Mode);
+ /* Write to SPIx CR1 */
+ SPIx->CR1 = tmpreg;
+
+ /* Activate the SPI mode (Reset I2SMOD bit in I2SCFGR register) */
+ SPIx->I2SCFGR &= (uint16_t)~((uint16_t)SPI_I2SCFGR_I2SMOD);
+}
+
+/**
+ * @brief Fills each I2S_InitStruct member with its default value.
+ * @param I2S_InitStruct: pointer to a I2S_InitTypeDef structure which will be initialized.
+ * @retval None
+ */
+void I2S_StructInit(I2S_InitTypeDef* I2S_InitStruct)
+{
+/*--------------- Reset I2S init structure parameters values -----------------*/
+ /* Initialize the I2S_Mode member */
+ I2S_InitStruct->I2S_Mode = I2S_Mode_SlaveTx;
+
+ /* Initialize the I2S_Standard member */
+ I2S_InitStruct->I2S_Standard = I2S_Standard_Phillips;
+
+ /* Initialize the I2S_DataFormat member */
+ I2S_InitStruct->I2S_DataFormat = I2S_DataFormat_16b;
+
+ /* Initialize the I2S_MCLKOutput member */
+ I2S_InitStruct->I2S_MCLKOutput = I2S_MCLKOutput_Disable;
+
+ /* Initialize the I2S_AudioFreq member */
+ I2S_InitStruct->I2S_AudioFreq = I2S_AudioFreq_Default;
+
+ /* Initialize the I2S_CPOL member */
+ I2S_InitStruct->I2S_CPOL = I2S_CPOL_Low;
+}
+
+/**
+ * @brief Initializes the SPIx peripheral according to the specified
+ * parameters in the I2S_InitStruct.
+ * @param SPIx: where x can be 1 to select the SPI peripheral (configured in I2S mode).
+ * @param I2S_InitStruct: pointer to an I2S_InitTypeDef structure that
+ * contains the configuration information for the specified SPI peripheral
+ * configured in I2S mode.
+ * @note This function calculates the optimal prescaler needed to obtain the most
+ * accurate audio frequency (depending on the I2S clock source, the PLL values
+ * and the product configuration). But in case the prescaler value is greater
+ * than 511, the default value (0x02) will be configured instead.
+ * @retval None
+ */
+void I2S_Init(SPI_TypeDef* SPIx, I2S_InitTypeDef* I2S_InitStruct)
+{
+ uint16_t tmpreg = 0, i2sdiv = 2, i2sodd = 0, packetlength = 1;
+ uint32_t tmp = 0;
+ RCC_ClocksTypeDef RCC_Clocks;
+ uint32_t sourceclock = 0;
+
+ /* Check the I2S parameters */
+ assert_param(IS_SPI_1_PERIPH(SPIx));
+ assert_param(IS_I2S_MODE(I2S_InitStruct->I2S_Mode));
+ assert_param(IS_I2S_STANDARD(I2S_InitStruct->I2S_Standard));
+ assert_param(IS_I2S_DATA_FORMAT(I2S_InitStruct->I2S_DataFormat));
+ assert_param(IS_I2S_MCLK_OUTPUT(I2S_InitStruct->I2S_MCLKOutput));
+ assert_param(IS_I2S_AUDIO_FREQ(I2S_InitStruct->I2S_AudioFreq));
+ assert_param(IS_I2S_CPOL(I2S_InitStruct->I2S_CPOL));
+
+/*----------------------- SPIx I2SCFGR & I2SPR Configuration -----------------*/
+ /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */
+ SPIx->I2SCFGR &= I2SCFGR_CLEAR_Mask;
+ SPIx->I2SPR = 0x0002;
+
+ /* Get the I2SCFGR register value */
+ tmpreg = SPIx->I2SCFGR;
+
+ /* If the default value has to be written, reinitialize i2sdiv and i2sodd*/
+ if(I2S_InitStruct->I2S_AudioFreq == I2S_AudioFreq_Default)
+ {
+ i2sodd = (uint16_t)0;
+ i2sdiv = (uint16_t)2;
+ }
+ /* If the requested audio frequency is not the default, compute the prescaler */
+ else
+ {
+ /* Check the frame length (For the Prescaler computing) */
+ if(I2S_InitStruct->I2S_DataFormat == I2S_DataFormat_16b)
+ {
+ /* Packet length is 16 bits */
+ packetlength = 1;
+ }
+ else
+ {
+ /* Packet length is 32 bits */
+ packetlength = 2;
+ }
+
+ /* I2S Clock source is System clock: Get System Clock frequency */
+ RCC_GetClocksFreq(&RCC_Clocks);
+
+ /* Get the source clock value: based on System Clock value */
+ sourceclock = RCC_Clocks.SYSCLK_Frequency;
+
+ /* Compute the Real divider depending on the MCLK output state with a floating point */
+ if(I2S_InitStruct->I2S_MCLKOutput == I2S_MCLKOutput_Enable)
+ {
+ /* MCLK output is enabled */
+ tmp = (uint16_t)(((((sourceclock / 256) * 10) / I2S_InitStruct->I2S_AudioFreq)) + 5);
+ }
+ else
+ {
+ /* MCLK output is disabled */
+ tmp = (uint16_t)(((((sourceclock / (32 * packetlength)) *10 ) / I2S_InitStruct->I2S_AudioFreq)) + 5);
+ }
+
+ /* Remove the floating point */
+ tmp = tmp / 10;
+
+ /* Check the parity of the divider */
+ i2sodd = (uint16_t)(tmp & (uint16_t)0x0001);
+
+ /* Compute the i2sdiv prescaler */
+ i2sdiv = (uint16_t)((tmp - i2sodd) / 2);
+
+ /* Get the Mask for the Odd bit (SPI_I2SPR[8]) register */
+ i2sodd = (uint16_t) (i2sodd << 8);
+ }
+
+ /* Test if the divider is 1 or 0 or greater than 0xFF */
+ if ((i2sdiv < 2) || (i2sdiv > 0xFF))
+ {
+ /* Set the default values */
+ i2sdiv = 2;
+ i2sodd = 0;
+ }
+
+ /* Write to SPIx I2SPR register the computed value */
+ SPIx->I2SPR = (uint16_t)(i2sdiv | (uint16_t)(i2sodd | (uint16_t)I2S_InitStruct->I2S_MCLKOutput));
+
+ /* Configure the I2S with the SPI_InitStruct values */
+ tmpreg |= (uint16_t)(SPI_I2SCFGR_I2SMOD | (uint16_t)(I2S_InitStruct->I2S_Mode | \
+ (uint16_t)(I2S_InitStruct->I2S_Standard | (uint16_t)(I2S_InitStruct->I2S_DataFormat | \
+ (uint16_t)I2S_InitStruct->I2S_CPOL))));
+
+ /* Write to SPIx I2SCFGR */
+ SPIx->I2SCFGR = tmpreg;
+}
+
+/**
+ * @brief Enables or disables the specified SPI peripheral.
+ * @param SPIx: where x can be 1 to select the SPI peripheral.
+ * @param NewState: new state of the SPIx peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected SPI peripheral */
+ SPIx->CR1 |= SPI_CR1_SPE;
+ }
+ else
+ {
+ /* Disable the selected SPI peripheral */
+ SPIx->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_SPE);
+ }
+}
+
+/**
+ * @brief Enables or disables the TI Mode.
+ *
+ * @note This function can be called only after the SPI_Init() function has
+ * been called.
+ * @note When TI mode is selected, the control bits SSM, SSI, CPOL and CPHA
+ * are not taken into consideration and are configured by hardware
+ * respectively to the TI mode requirements.
+ *
+ * @param SPIx: where x can be 1 to select the SPI peripheral.
+ * @param NewState: new state of the selected SPI TI communication mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void SPI_TIModeCmd(SPI_TypeDef* SPIx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the TI mode for the selected SPI peripheral */
+ SPIx->CR2 |= SPI_CR2_FRF;
+ }
+ else
+ {
+ /* Disable the TI mode for the selected SPI peripheral */
+ SPIx->CR2 &= (uint16_t)~((uint16_t)SPI_CR2_FRF);
+ }
+}
+
+/**
+ * @brief Enables or disables the specified SPI peripheral (in I2S mode).
+ * @param SPIx: where x can be 1 to select the SPI peripheral.
+ * @param NewState: new state of the SPIx peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2S_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_1_PERIPH(SPIx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected SPI peripheral in I2S mode */
+ SPIx->I2SCFGR |= SPI_I2SCFGR_I2SE;
+ }
+ else
+ {
+ /* Disable the selected SPI peripheral in I2S mode */
+ SPIx->I2SCFGR &= (uint16_t)~((uint16_t)SPI_I2SCFGR_I2SE);
+ }
+}
+
+/**
+ * @brief Configures the data size for the selected SPI.
+ * @param SPIx: where x can be 1 to select the SPI peripheral.
+ * @param SPI_DataSize: specifies the SPI data size.
+ * For the SPIx peripheral this parameter can be one of the following values:
+ * @arg SPI_DataSize_4b: Set data size to 4 bits
+ * @arg SPI_DataSize_5b: Set data size to 5 bits
+ * @arg SPI_DataSize_6b: Set data size to 6 bits
+ * @arg SPI_DataSize_7b: Set data size to 7 bits
+ * @arg SPI_DataSize_8b: Set data size to 8 bits
+ * @arg SPI_DataSize_9b: Set data size to 9 bits
+ * @arg SPI_DataSize_10b: Set data size to 10 bits
+ * @arg SPI_DataSize_11b: Set data size to 11 bits
+ * @arg SPI_DataSize_12b: Set data size to 12 bits
+ * @arg SPI_DataSize_13b: Set data size to 13 bits
+ * @arg SPI_DataSize_14b: Set data size to 14 bits
+ * @arg SPI_DataSize_15b: Set data size to 15 bits
+ * @arg SPI_DataSize_16b: Set data size to 16 bits
+ * @retval None
+ */
+void SPI_DataSizeConfig(SPI_TypeDef* SPIx, uint16_t SPI_DataSize)
+{
+ uint16_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_SPI_DATA_SIZE(SPI_DataSize));
+ /* Read the CR2 register */
+ tmpreg = SPIx->CR2;
+ /* Clear DS[3:0] bits */
+ tmpreg &= (uint16_t)~SPI_CR2_DS;
+ /* Set new DS[3:0] bits value */
+ tmpreg |= SPI_DataSize;
+ SPIx->CR2 = tmpreg;
+}
+
+/**
+ * @brief Configures the FIFO reception threshold for the selected SPI.
+ * @param SPIx: where x can be 1 to select the SPI peripheral.
+ * @param SPI_RxFIFOThreshold: specifies the FIFO reception threshold.
+ * This parameter can be one of the following values:
+ * @arg SPI_RxFIFOThreshold_HF: RXNE event is generated if the FIFO
+ * level is greater or equal to 1/2.
+ * @arg SPI_RxFIFOThreshold_QF: RXNE event is generated if the FIFO
+ * level is greater or equal to 1/4.
+ * @retval None
+ */
+void SPI_RxFIFOThresholdConfig(SPI_TypeDef* SPIx, uint16_t SPI_RxFIFOThreshold)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_SPI_RX_FIFO_THRESHOLD(SPI_RxFIFOThreshold));
+
+ /* Clear FRXTH bit */
+ SPIx->CR2 &= (uint16_t)~((uint16_t)SPI_CR2_FRXTH);
+
+ /* Set new FRXTH bit value */
+ SPIx->CR2 |= SPI_RxFIFOThreshold;
+}
+
+/**
+ * @brief Selects the data transfer direction in bidirectional mode for the specified SPI.
+ * @param SPIx: where x can be 1 to select the SPI peripheral.
+ * @param SPI_Direction: specifies the data transfer direction in bidirectional mode.
+ * This parameter can be one of the following values:
+ * @arg SPI_Direction_Tx: Selects Tx transmission direction
+ * @arg SPI_Direction_Rx: Selects Rx receive direction
+ * @retval None
+ */
+void SPI_BiDirectionalLineConfig(SPI_TypeDef* SPIx, uint16_t SPI_Direction)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_SPI_DIRECTION(SPI_Direction));
+ if (SPI_Direction == SPI_Direction_Tx)
+ {
+ /* Set the Tx only mode */
+ SPIx->CR1 |= SPI_Direction_Tx;
+ }
+ else
+ {
+ /* Set the Rx only mode */
+ SPIx->CR1 &= SPI_Direction_Rx;
+ }
+}
+
+/**
+ * @brief Configures internally by software the NSS pin for the selected SPI.
+ * @note This function can be called only after the SPI_Init() function has
+ * been called.
+ * @param SPIx: where x can be to select the SPI peripheral.
+ * @param SPI_NSSInternalSoft: specifies the SPI NSS internal state.
+ * This parameter can be one of the following values:
+ * @arg SPI_NSSInternalSoft_Set: Set NSS pin internally
+ * @arg SPI_NSSInternalSoft_Reset: Reset NSS pin internally
+ * @retval None
+ */
+void SPI_NSSInternalSoftwareConfig(SPI_TypeDef* SPIx, uint16_t SPI_NSSInternalSoft)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_SPI_NSS_INTERNAL(SPI_NSSInternalSoft));
+
+ if (SPI_NSSInternalSoft != SPI_NSSInternalSoft_Reset)
+ {
+ /* Set NSS pin internally by software */
+ SPIx->CR1 |= SPI_NSSInternalSoft_Set;
+ }
+ else
+ {
+ /* Reset NSS pin internally by software */
+ SPIx->CR1 &= SPI_NSSInternalSoft_Reset;
+ }
+}
+
+/**
+ * @brief Enables or disables the SS output for the selected SPI.
+ * @note This function can be called only after the SPI_Init() function has
+ * been called and the NSS hardware management mode is selected.
+ * @param SPIx: where x can be 1 to select the SPI peripheral.
+ * @param NewState: new state of the SPIx SS output.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void SPI_SSOutputCmd(SPI_TypeDef* SPIx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected SPI SS output */
+ SPIx->CR2 |= SPI_CR2_SSOE;
+ }
+ else
+ {
+ /* Disable the selected SPI SS output */
+ SPIx->CR2 &= (uint16_t)~((uint16_t)SPI_CR2_SSOE);
+ }
+}
+
+/**
+ * @brief Enables or disables the NSS pulse management mode.
+ * @note This function can be called only after the SPI_Init() function has
+ * been called.
+ * @note When TI mode is selected, the control bits NSSP is not taken into
+ * consideration and are configured by hardware respectively to the
+ * TI mode requirements.
+ * @param SPIx: where x can be 1 to select the SPI peripheral.
+ * @param NewState: new state of the NSS pulse management mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void SPI_NSSPulseModeCmd(SPI_TypeDef* SPIx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the NSS pulse management mode */
+ SPIx->CR2 |= SPI_CR2_NSSP;
+ }
+ else
+ {
+ /* Disable the NSS pulse management mode */
+ SPIx->CR2 &= (uint16_t)~((uint16_t)SPI_CR2_NSSP);
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup SPI_Group2 Data transfers functions
+ * @brief Data transfers functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Data transfers functions #####
+ ===============================================================================
+ [..] This section provides a set of functions allowing to manage the SPI or I2S
+ data transfers.
+
+ [..] In reception, data are received and then stored into an internal Rx buffer while
+ In transmission, data are first stored into an internal Tx buffer before being
+ transmitted.
+
+ [..] The read access of the SPI_DR register can be done using
+ SPI_ReceiveData8() (when data size is equal or inferior than 8bits) and.
+ SPI_I2S_ReceiveData16() (when data size is superior than 8bits)function
+ and returns the Rx buffered value. Whereas a write access to the SPI_DR
+ can be done using SPI_SendData8() (when data size is equal or inferior than 8bits)
+ and SPI_I2S_SendData16() (when data size is superior than 8bits) function
+ and stores the written data into Tx buffer.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Transmits a Data through the SPIx/I2Sx peripheral.
+ * @param SPIx: where x can be 1 in SPI mode to select the SPI peripheral.
+ * @param Data: Data to be transmitted.
+ * @retval None
+ */
+void SPI_SendData8(SPI_TypeDef* SPIx, uint8_t Data)
+{
+ uint32_t spixbase = 0x00;
+
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+
+ spixbase = (uint32_t)SPIx;
+ spixbase += 0x0C;
+
+ *(__IO uint8_t *) spixbase = Data;
+}
+
+/**
+ * @brief Transmits a Data through the SPIx/I2Sx peripheral.
+ * @param SPIx: where x can be 1 in SPI mode or 1 in I2S mode to select
+ * the SPI peripheral.
+ * @param Data: Data to be transmitted.
+ * @retval None
+ */
+void SPI_I2S_SendData16(SPI_TypeDef* SPIx, uint16_t Data)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+
+ SPIx->DR = (uint16_t)Data;
+}
+
+/**
+ * @brief Returns the most recent received data by the SPIx/I2Sx peripheral.
+ * @param SPIx: where x can be 1 in SPI mode to select the SPI peripheral.
+ * @retval The value of the received data.
+ */
+uint8_t SPI_ReceiveData8(SPI_TypeDef* SPIx)
+{
+ uint32_t spixbase = 0x00;
+
+ spixbase = (uint32_t)SPIx;
+ spixbase += 0x0C;
+
+ return *(__IO uint8_t *) spixbase;
+}
+
+/**
+ * @brief Returns the most recent received data by the SPIx peripheral.
+ * @param SPIx: where x can be 1 in SPI mode or 1 in I2S mode to select
+ * the SPI peripheral.
+ * @retval The value of the received data.
+ */
+uint16_t SPI_I2S_ReceiveData16(SPI_TypeDef* SPIx)
+{
+ return SPIx->DR;
+}
+/**
+ * @}
+ */
+
+/** @defgroup SPI_Group3 Hardware CRC Calculation functions
+ * @brief Hardware CRC Calculation functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Hardware CRC Calculation functions #####
+ ===============================================================================
+ [..] This section provides a set of functions allowing to manage the SPI CRC hardware
+ calculation.SPI communication using CRC is possible through the following procedure:
+
+ (#) Program the Data direction, Polarity, Phase, First Data, Baud Rate Prescaler,
+ Slave Management, Peripheral Mode and CRC Polynomial values using the SPI_Init()
+ function.
+ (#) Enable the CRC calculation using the SPI_CalculateCRC() function.
+ (#) Enable the SPI using the SPI_Cmd() function
+ (#) Before writing the last data to the TX buffer, set the CRCNext bit using the
+ SPI_TransmitCRC() function to indicate that after transmission of the last
+ data, the CRC should be transmitted.
+ (#) After transmitting the last data, the SPI transmits the CRC. The SPI_CR1_CRCNEXT
+ bit is reset. The CRC is also received and compared against the SPI_RXCRCR
+ value.
+ If the value does not match, the SPI_FLAG_CRCERR flag is set and an interrupt
+ can be generated when the SPI_I2S_IT_ERR interrupt is enabled.
+
+ -@-
+ (+@) It is advised to don't read the calculate CRC values during the communication.
+ (+@) When the SPI is in slave mode, be careful to enable CRC calculation only
+ when the clock is stable, that is, when the clock is in the steady state.
+ If not, a wrong CRC calculation may be done. In fact, the CRC is sensitive
+ to the SCK slave input clock as soon as CRCEN is set, and this, whatever
+ the value of the SPE bit.
+ (+@) With high bitrate frequencies, be careful when transmitting the CRC.
+ As the number of used CPU cycles has to be as low as possible in the CRC
+ transfer phase, it is forbidden to call software functions in the CRC
+ transmission sequence to avoid errors in the last data and CRC reception.
+ In fact, CRCNEXT bit has to be written before the end of the transmission/reception
+ of the last data.
+ (+@) For high bit rate frequencies, it is advised to use the DMA mode to avoid the
+ degradation of the SPI speed performance due to CPU accesses impacting the
+ SPI bandwidth.
+ (+@) When the hk32f030m are configured as slaves and the NSS hardware mode is
+ used, the NSS pin needs to be kept low between the data phase and the CRC
+ phase.
+ (+@) When the SPI is configured in slave mode with the CRC feature enabled, CRC
+ calculation takes place even if a high level is applied on the NSS pin.
+ This may happen for example in case of a multislave environment where the
+ communication master addresses slaves alternately.
+ (+@) Between a slave deselection (high level on NSS) and a new slave selection
+ (low level on NSS), 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.
+
+ -@- To clear the CRC, follow the procedure below:
+ (#@) Disable SPI using the SPI_Cmd() function
+ (#@) Disable the CRC calculation using the SPI_CalculateCRC() function.
+ (#@) Enable the CRC calculation using the SPI_CalculateCRC() function.
+ (#@) Enable SPI using the SPI_Cmd() function.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Configures the CRC calculation length for the selected SPI.
+ * @note This function can be called only after the SPI_Init() function has
+ * been called.
+ * @param SPIx: where x can be 1 to select the SPI peripheral.
+ * @param SPI_CRCLength: specifies the SPI CRC calculation length.
+ * This parameter can be one of the following values:
+ * @arg SPI_CRCLength_8b: Set CRC Calculation to 8 bits
+ * @arg SPI_CRCLength_16b: Set CRC Calculation to 16 bits
+ * @retval None
+ */
+void SPI_CRCLengthConfig(SPI_TypeDef* SPIx, uint16_t SPI_CRCLength)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_SPI_CRC_LENGTH(SPI_CRCLength));
+
+ /* Clear CRCL bit */
+ SPIx->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_CRCL);
+
+ /* Set new CRCL bit value */
+ SPIx->CR1 |= SPI_CRCLength;
+}
+
+/**
+ * @brief Enables or disables the CRC value calculation of the transferred bytes.
+ * @note This function can be called only after the SPI_Init() function has
+ * been called.
+ * @param SPIx: where x can be 1 to select the SPI peripheral.
+ * @param NewState: new state of the SPIx CRC value calculation.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void SPI_CalculateCRC(SPI_TypeDef* SPIx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected SPI CRC calculation */
+ SPIx->CR1 |= SPI_CR1_CRCEN;
+ }
+ else
+ {
+ /* Disable the selected SPI CRC calculation */
+ SPIx->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_CRCEN);
+ }
+}
+
+/**
+ * @brief Transmit the SPIx CRC value.
+ * @param SPIx: where x can be 1 to select the SPI peripheral.
+ * @retval None
+ */
+void SPI_TransmitCRC(SPI_TypeDef* SPIx)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+
+ /* Enable the selected SPI CRC transmission */
+ SPIx->CR1 |= SPI_CR1_CRCNEXT;
+}
+
+/**
+ * @brief Returns the transmit or the receive CRC register value for the specified SPI.
+ * @param SPIx: where x can be 1 to select the SPI peripheral.
+ * @param SPI_CRC: specifies the CRC register to be read.
+ * This parameter can be one of the following values:
+ * @arg SPI_CRC_Tx: Selects Tx CRC register
+ * @arg SPI_CRC_Rx: Selects Rx CRC register
+ * @retval The selected CRC register value..
+ */
+uint16_t SPI_GetCRC(SPI_TypeDef* SPIx, uint8_t SPI_CRC)
+{
+ uint16_t crcreg = 0;
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_SPI_CRC(SPI_CRC));
+
+ if (SPI_CRC != SPI_CRC_Rx)
+ {
+ /* Get the Tx CRC register */
+ crcreg = SPIx->TXCRCR;
+ }
+ else
+ {
+ /* Get the Rx CRC register */
+ crcreg = SPIx->RXCRCR;
+ }
+ /* Return the selected CRC register */
+ return crcreg;
+}
+
+/**
+ * @brief Returns the CRC Polynomial register value for the specified SPI.
+ * @param SPIx: where x can be 1 to select the SPI peripheral.
+ * @retval The CRC Polynomial register value.
+ */
+uint16_t SPI_GetCRCPolynomial(SPI_TypeDef* SPIx)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+
+ /* Return the CRC polynomial register */
+ return SPIx->CRCPR;
+}
+
+/**
+ * @}
+ */
+
+
+
+/** @defgroup SPI_Group5 Interrupts and flags management functions
+ * @brief Interrupts and flags management functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Interrupts and flags management functions #####
+ ===============================================================================
+ [..] This section provides a set of functions allowing to configure the SPI/I2S Interrupts
+ sources and check or clear the flags or pending bits status.
+ The user should identify which mode will be used in his application to manage
+ the communication: Polling mode, Interrupt mode or DMA mode.
+
+ *** Polling Mode ***
+ ====================
+ [..] In Polling Mode, the SPI/I2S communication can be managed by 9 flags:
+ (#) SPI_I2S_FLAG_TXE : to indicate the status of the transmit buffer register
+ (#) SPI_I2S_FLAG_RXNE : to indicate the status of the receive buffer register
+ (#) SPI_I2S_FLAG_BSY : to indicate the state of the communication layer of the SPI.
+ (#) SPI_FLAG_CRCERR : to indicate if a CRC Calculation error occur
+ (#) SPI_FLAG_MODF : to indicate if a Mode Fault error occur
+ (#) SPI_I2S_FLAG_OVR : to indicate if an Overrun error occur
+ (#) SPI_I2S_FLAG_FRE: to indicate a Frame Format error occurs.
+ (#) I2S_FLAG_UDR: to indicate an Underrun error occurs.
+ (#) I2S_FLAG_CHSIDE: to indicate Channel Side.
+
+ [..]
+ (@)Do not use the BSY flag to handle each data transmission or reception. It is better
+ to use the TXE and RXNE flags instead.
+
+ [..] In this Mode it is advised to use the following functions:
+ (+) FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);
+ (+) void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);
+
+ *** Interrupt Mode ***
+ ======================
+ [..] In Interrupt Mode, the SPI/I2S communication can be managed by 3 interrupt sources
+ and 5 pending bits:
+ [..] Pending Bits:
+ (#) SPI_I2S_IT_TXE : to indicate the status of the transmit buffer register
+ (#) SPI_I2S_IT_RXNE : to indicate the status of the receive buffer register
+ (#) SPI_I2S_IT_OVR : to indicate if an Overrun error occur
+ (#) I2S_IT_UDR : to indicate an Underrun Error occurs.
+ (#) SPI_I2S_FLAG_FRE : to indicate a Frame Format error occurs.
+
+ [..] Interrupt Source:
+ (#) SPI_I2S_IT_TXE: specifies the interrupt source for the Tx buffer empty
+ interrupt.
+ (#) SPI_I2S_IT_RXNE : specifies the interrupt source for the Rx buffer not
+ empty interrupt.
+ (#) SPI_I2S_IT_ERR : specifies the interrupt source for the errors interrupt.
+
+ [..] In this Mode it is advised to use the following functions:
+ (+) void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState);
+ (+) ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT);
+
+ *** FIFO Status ***
+ ===================
+ [..] It is possible to monitor the FIFO status when a transfer is ongoing using the
+ following function:
+ (+) uint32_t SPI_GetFIFOStatus(uint8_t SPI_FIFO_Direction);
+
+ *** DMA Mode ***
+ ================
+ [..] In DMA Mode, the SPI communication can be managed by 2 DMA Channel
+ requests:
+ (#) SPI_I2S_DMAReq_Tx: specifies the Tx buffer DMA transfer request.
+ (#) SPI_I2S_DMAReq_Rx: specifies the Rx buffer DMA transfer request.
+
+ [..] In this Mode it is advised to use the following function:
+ (+) void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState).
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the specified SPI/I2S interrupts.
+ * @param SPIx: where x can be 1 in SPI mode or 1 in I2S mode to select
+ * the SPI peripheral.
+ * @param SPI_I2S_IT: specifies the SPI interrupt source to be enabled or disabled.
+ * This parameter can be one of the following values:
+ * @arg SPI_I2S_IT_TXE: Tx buffer empty interrupt mask
+ * @arg SPI_I2S_IT_RXNE: Rx buffer not empty interrupt mask
+ * @arg SPI_I2S_IT_ERR: Error interrupt mask
+ * @param NewState: new state of the specified SPI interrupt.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState)
+{
+ uint16_t itpos = 0, itmask = 0 ;
+
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ assert_param(IS_SPI_I2S_CONFIG_IT(SPI_I2S_IT));
+
+ /* Get the SPI IT index */
+ itpos = SPI_I2S_IT >> 4;
+
+ /* Set the IT mask */
+ itmask = (uint16_t)1 << (uint16_t)itpos;
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected SPI interrupt */
+ SPIx->CR2 |= itmask;
+ }
+ else
+ {
+ /* Disable the selected SPI interrupt */
+ SPIx->CR2 &= (uint16_t)~itmask;
+ }
+}
+
+/**
+ * @brief Returns the current SPIx Transmission FIFO filled level.
+ * @param SPIx: where x can be 1 to select the SPI peripheral.
+ * @retval The Transmission FIFO filling state.
+ * - SPI_TransmissionFIFOStatus_Empty: when FIFO is empty
+ * - SPI_TransmissionFIFOStatus_1QuarterFull: if more than 1 quarter-full.
+ * - SPI_TransmissionFIFOStatus_HalfFull: if more than 1 half-full.
+ * - SPI_TransmissionFIFOStatus_Full: when FIFO is full.
+ */
+uint16_t SPI_GetTransmissionFIFOStatus(SPI_TypeDef* SPIx)
+{
+ /* Get the SPIx Transmission FIFO level bits */
+ return (uint16_t)((SPIx->SR & SPI_SR_FTLVL));
+}
+
+/**
+ * @brief Returns the current SPIx Reception FIFO filled level.
+ * @param SPIx: where x can be 1 to select the SPI peripheral.
+ * @retval The Reception FIFO filling state.
+ * - SPI_ReceptionFIFOStatus_Empty: when FIFO is empty
+ * - SPI_ReceptionFIFOStatus_1QuarterFull: if more than 1 quarter-full.
+ * - SPI_ReceptionFIFOStatus_HalfFull: if more than 1 half-full.
+ * - SPI_ReceptionFIFOStatus_Full: when FIFO is full.
+ */
+uint16_t SPI_GetReceptionFIFOStatus(SPI_TypeDef* SPIx)
+{
+ /* Get the SPIx Reception FIFO level bits */
+ return (uint16_t)((SPIx->SR & SPI_SR_FRLVL));
+}
+
+/**
+ * @brief Checks whether the specified SPI flag is set or not.
+ * @param SPIx: where x can be 1 in SPI mode or 1 in I2S mode to select
+ * the SPI peripheral.
+ * @param SPI_I2S_FLAG: specifies the SPI flag to check.
+ * This parameter can be one of the following values:
+ * @arg SPI_I2S_FLAG_TXE: Transmit buffer empty flag.
+ * @arg SPI_I2S_FLAG_RXNE: Receive buffer not empty flag.
+ * @arg SPI_I2S_FLAG_BSY: Busy flag.
+ * @arg SPI_I2S_FLAG_OVR: Overrun flag.
+ * @arg SPI_FLAG_MODF: Mode Fault flag.
+ * @arg SPI_FLAG_CRCERR: CRC Error flag.
+ * @arg SPI_I2S_FLAG_FRE: TI frame format error flag.
+ * @arg I2S_FLAG_UDR: Underrun Error flag.
+ * @arg I2S_FLAG_CHSIDE: Channel Side flag.
+ * @retval The new state of SPI_I2S_FLAG (SET or RESET).
+ */
+FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG)
+{
+ FlagStatus bitstatus = RESET;
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_SPI_I2S_GET_FLAG(SPI_I2S_FLAG));
+
+ /* Check the status of the specified SPI flag */
+ if ((SPIx->SR & SPI_I2S_FLAG) != (uint16_t)RESET)
+ {
+ /* SPI_I2S_FLAG is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* SPI_I2S_FLAG is reset */
+ bitstatus = RESET;
+ }
+ /* Return the SPI_I2S_FLAG status */
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the SPIx CRC Error (CRCERR) flag.
+ * @param SPIx: where x can be 1 to select the SPI peripheral.
+ * @param SPI_I2S_FLAG: specifies the SPI flag to clear.
+ * This function clears only CRCERR flag.
+ * @note OVR (OverRun error) flag is cleared by software sequence: a read
+ * operation to SPI_DR register (SPI_I2S_ReceiveData()) followed by
+ * a read operation to SPI_SR register (SPI_I2S_GetFlagStatus()).
+ * @note MODF (Mode Fault) flag is cleared by software sequence: a read/write
+ * operation to SPI_SR register (SPI_I2S_GetFlagStatus()) followed by
+ * a write operation to SPI_CR1 register (SPI_Cmd() to enable the SPI).
+ * @retval None
+ */
+void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_SPI_CLEAR_FLAG(SPI_I2S_FLAG));
+
+ /* Clear the selected SPI CRC Error (CRCERR) flag */
+ SPIx->SR = (uint16_t)~SPI_I2S_FLAG;
+}
+
+/**
+ * @brief Checks whether the specified SPI/I2S interrupt has occurred or not.
+ * @param SPIx: where x can be 1 or 2 in SPI mode or 1 in I2S mode to select
+ * the SPI peripheral.
+ * @param SPI_I2S_IT: specifies the SPI interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg SPI_I2S_IT_TXE: Transmit buffer empty interrupt.
+ * @arg SPI_I2S_IT_RXNE: Receive buffer not empty interrupt.
+ * @arg SPI_IT_MODF: Mode Fault interrupt.
+ * @arg SPI_I2S_IT_OVR: Overrun interrupt.
+ * @arg I2S_IT_UDR: Underrun interrupt.
+ * @arg SPI_I2S_IT_FRE: Format Error interrupt.
+ * @retval The new state of SPI_I2S_IT (SET or RESET).
+ */
+ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT)
+{
+ ITStatus bitstatus = RESET;
+ uint16_t itpos = 0, itmask = 0, enablestatus = 0;
+
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_SPI_I2S_GET_IT(SPI_I2S_IT));
+
+ /* Get the SPI_I2S_IT index */
+ itpos = 0x01 << (SPI_I2S_IT & 0x0F);
+
+ /* Get the SPI_I2S_IT IT mask */
+ itmask = SPI_I2S_IT >> 4;
+
+ /* Set the IT mask */
+ itmask = 0x01 << itmask;
+
+ /* Get the SPI_I2S_IT enable bit status */
+ enablestatus = (SPIx->CR2 & itmask) ;
+
+ /* Check the status of the specified SPI interrupt */
+ if (((SPIx->SR & itpos) != (uint16_t)RESET) && enablestatus)
+ {
+ /* SPI_I2S_IT is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* SPI_I2S_IT is reset */
+ bitstatus = RESET;
+ }
+ /* Return the SPI_I2S_IT status */
+ return bitstatus;
+}
+
+
+
+
+
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_syscfg.c b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_syscfg.c
new file mode 100644
index 0000000..df1dc00
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_syscfg.c
@@ -0,0 +1,105 @@
+/**
+ ******************************************************************************
+ * @file hk32f030m_syscfg.c
+ * @author Rakan.zhang
+ * @version V1.0
+ * @brief API file of PWR module
+ * @changelist
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "hk32f030m_syscfg.h"
+#include "hk32f030m_rcc.h"
+
+
+/** @defgroup SYSCFG
+ * @brief SYSCFG driver modules
+ * @{
+ */
+
+/**
+ * @brief Deinitializes the Alternate Functions (remap and EXTI configuration)
+ * registers to their default reset values.
+ * @param None
+ * @retval None
+ */
+void SYSCFG_DeInit(void)
+{
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, ENABLE);
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, DISABLE);
+}
+
+/**
+ * @brief Cortex-m0 lockup output to tim1 break input connected or disconnected.
+ * @param Lockup_lockOnOff: To TIM1 break input onoff.
+ * This parameter can be one of the following values:
+ * @arg SYSCFG_Lockup_TIM1Break_ON: Cortex-m0 lockup output to tim1 break input connected
+ * @arg SYSCFG_Lockup_TIM1Break_OFF:Cortex-m0 lockup output to tim1 break input disconnected
+ * @retval None
+ */
+void SYSCFG_Lockup_Tim1BreakConfig(uint8_t Lockup_lockOnOff)
+{
+ uint32_t temp = 0;
+ /* Check the parameters */
+ assert_param(IS_SYSCFG_LOCKUP_TIM1BREAK_ONOFF(Lockup_lockOnOff));
+ /*select SYSYCFG CFGR1 register*/
+ temp = SYSCFG->CFGR1;
+ /* clear mem_mode */
+ temp &= MEM_LOCKUP_OUT_MASK;
+ /* set memoryRemap value*/
+ temp |= Lockup_lockOnOff;
+
+ SYSCFG->CFGR1 |= temp;
+}
+
+/**
+ * @brief Changes the mapping of the specified pin.
+ * @param SYSCFG_MemoryRemap: selects the memory remapping.
+ * This parameter can be one of the following values:
+ * @arg SYSCFG_MemoryRemap_Flash: Main Flash memory mapped at 0x00000000
+ * @arg SYSCFG_MemoryRemap_SRAM: Embedded SRAM (2kB) mapped at 0x00000000
+ * @retval None
+ */
+void SYSCFG_MemoryRemapConfig(uint8_t SYSCFG_MemoryRemap)
+{
+ uint32_t temp = 0;
+ /* Check the parameters */
+ assert_param(IS_SYSCFG_MEMORY_REMAP_CONFING(SYSCFG_MemoryRemap));
+ /*select SYSYCFG CFGR1 register*/
+ temp = SYSCFG->CFGR1;
+ /* clear mem_mode */
+ temp &= MEM_REMAP_MASK;
+ /* set memoryRemap value*/
+ temp |= SYSCFG_MemoryRemap;
+
+ SYSCFG->CFGR1 |= temp;
+}
+/**
+ * @brief Selects the GPIO pin used as EXTI Line.
+ * @param EXTI_PortSourceGPIOx : selects the GPIO port to be used as source for
+ * EXTI lines where x can be (A..D)
+ *
+ * @param EXTI_PinSourcex: specifies the EXTI line to be configured.
+ * This parameter can be EXTI_PinSourcex where x can be (0..15)
+ *
+ * @retval None
+ */
+void SYSCFG_EXTILineConfig(uint8_t EXTI_PortSourceGPIOx, uint8_t EXTI_PinSourcex)
+{
+ uint32_t tmp = 0x00;
+
+ /* Check the parameters */
+ assert_param(IS_EXTI_PORT_SOURCE(EXTI_PortSourceGPIOx));
+ assert_param(IS_EXTI_PIN_SOURCE(EXTI_PinSourcex));
+
+ tmp = ((uint32_t)0x0F) << (0x04 * (EXTI_PinSourcex & (uint8_t)0x03));
+ SYSCFG->EXTICR[EXTI_PinSourcex >> 0x02] &= ~tmp;
+ SYSCFG->EXTICR[EXTI_PinSourcex >> 0x02] |= (((uint32_t)EXTI_PortSourceGPIOx) << (0x04 * (EXTI_PinSourcex & (uint8_t)0x03)));
+}
+
+
+/**
+ * @}
+ */
+
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_tim.c b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_tim.c
new file mode 100644
index 0000000..987999e
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_tim.c
@@ -0,0 +1,2953 @@
+/**
+ ******************************************************************************
+ * @file hk32f030m_tim.c
+ * @version V1.0.0
+ * @date 2019-12-25
+ * * @author Rakan.Z
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "hk32f030m_tim.h"
+#include "hk32f030m_rcc.h"
+
+/** @defgroup TIM
+ * @brief TIM driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+
+/* ---------------------- TIM registers bit mask ------------------------ */
+#define SMCR_ETR_MASK ((uint16_t)0x00FF)
+#define CCMR_OFFSET ((uint16_t)0x0018)
+#define CCER_CCE_SET ((uint16_t)0x0001)
+#define CCER_CCNE_SET ((uint16_t)0x0004)
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+
+static void TI1_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection,
+ uint16_t TIM_ICFilter);
+static void TI2_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection,
+ uint16_t TIM_ICFilter);
+static void TI3_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection,
+ uint16_t TIM_ICFilter);
+static void TI4_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection,
+ uint16_t TIM_ICFilter);
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup TIM_Private_Functions
+ * @{
+ */
+
+/** @defgroup TIM_Group1 TimeBase management functions
+ * @brief TimeBase management functions
+ *
+@verbatim
+ ===============================================================================
+ ##### TimeBase management functions #####
+ ===============================================================================
+
+ *** TIM Driver: how to use it in Timing(Time base) Mode ***
+ ===============================================================================
+ [..] To use the Timer in Timing(Time base) mode, the following steps are
+ mandatory:
+ (#) Enable TIM clock using
+ RCC_APBxPeriphClockCmd(RCC_APBxPeriph_TIMx, ENABLE) function.
+ (#) Fill the TIM_TimeBaseInitStruct with the desired parameters.
+ (#) Call TIM_TimeBaseInit(TIMx, &TIM_TimeBaseInitStruct) to configure
+ the Time Base unit with the corresponding configuration.
+ (#) Enable the NVIC if you need to generate the update interrupt.
+ (#) Enable the corresponding interrupt using the function
+ TIM_ITConfig(TIMx, TIM_IT_Update).
+ (#) Call the TIM_Cmd(ENABLE) function to enable the TIM counter.
+ [..]
+ (@) All other functions can be used seperatly to modify, if needed,
+ a specific feature of the Timer.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Deinitializes the TIMx peripheral registers to their default reset values.
+ * @param TIMx: where x can be 1, 2, 6 to select the TIM peripheral.
+ * @retval None
+ *
+ */
+void TIM_DeInit(TIM_TypeDef* TIMx)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+
+ if (TIMx == TIM1)
+ {
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM1, ENABLE);
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM1, DISABLE);
+ }
+ else if (TIMx == TIM2)
+ {
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM2, ENABLE);
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM2, DISABLE);
+ }
+ else if (TIMx == TIM6)
+ {
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM6, ENABLE);
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM6, DISABLE);
+ }
+
+}
+
+/**
+ * @brief Initializes the TIMx Time Base Unit peripheral according to
+ * the specified parameters in the TIM_TimeBaseInitStruct.
+ * @param TIMx: where x can be 1, 2, 6 to select the TIM
+ * peripheral.
+ * @param TIM_TimeBaseInitStruct: pointer to a TIM_TimeBaseInitTypeDef
+ * structure that contains the configuration information for
+ * the specified TIM peripheral.
+ * @retval None
+ */
+void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct)
+{
+ uint16_t tmpcr1 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ assert_param(IS_TIM_COUNTER_MODE(TIM_TimeBaseInitStruct->TIM_CounterMode));
+ assert_param(IS_TIM_CKD_DIV(TIM_TimeBaseInitStruct->TIM_ClockDivision));
+
+ tmpcr1 = TIMx->CR1;
+
+ if((TIMx == TIM1) || (TIMx == TIM2))
+ {
+ /* Select the Counter Mode */
+ tmpcr1 &= (uint16_t)(~((uint16_t)(TIM_CR1_DIR | TIM_CR1_CMS)));
+ tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_CounterMode;
+ }
+
+ if(TIMx != TIM6)
+ {
+ /* Set the clock division */
+ tmpcr1 &= (uint16_t)(~((uint16_t)TIM_CR1_CKD));
+ tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_ClockDivision;
+ }
+
+ TIMx->CR1 = tmpcr1;
+
+ /* Set the Autoreload value */
+ TIMx->ARR = TIM_TimeBaseInitStruct->TIM_Period ;
+
+ /* Set the Prescaler value */
+ TIMx->PSC = TIM_TimeBaseInitStruct->TIM_Prescaler;
+
+ if (TIMx == TIM1)
+ {
+ /* Set the Repetition Counter value */
+ TIMx->RCR = TIM_TimeBaseInitStruct->TIM_RepetitionCounter;
+ }
+
+ /* Generate an update event to reload the Prescaler and the Repetition counter
+ values immediately */
+ TIMx->EGR = TIM_PSCReloadMode_Immediate;
+}
+
+/**
+ * @brief Fills each TIM_TimeBaseInitStruct member with its default value.
+ * @param TIM_TimeBaseInitStruct: pointer to a TIM_TimeBaseInitTypeDef structure
+ * which will be initialized.
+ * @retval None
+ */
+void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct)
+{
+ /* Set the default configuration */
+ TIM_TimeBaseInitStruct->TIM_Period = 0xFFFFFFFF;
+ TIM_TimeBaseInitStruct->TIM_Prescaler = 0x0000;
+ TIM_TimeBaseInitStruct->TIM_ClockDivision = TIM_CKD_DIV1;
+ TIM_TimeBaseInitStruct->TIM_CounterMode = TIM_CounterMode_Up;
+ TIM_TimeBaseInitStruct->TIM_RepetitionCounter = 0x0000;
+}
+
+/**
+ * @brief Configures the TIMx Prescaler.
+ * @param TIMx: where x can be 1, 2, 6 to select the TIM peripheral.
+ * @param Prescaler: specifies the Prescaler Register value
+ * @param TIM_PSCReloadMode: specifies the TIM Prescaler Reload mode
+ * This parameter can be one of the following values:
+ * @arg TIM_PSCReloadMode_Update: The Prescaler is loaded at the update event.
+ * @arg TIM_PSCReloadMode_Immediate: The Prescaler is loaded immediatly.
+ * @retval None
+ */
+void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ assert_param(IS_TIM_PRESCALER_RELOAD(TIM_PSCReloadMode));
+
+ /* Set the Prescaler value */
+ TIMx->PSC = Prescaler;
+ /* Set or reset the UG Bit */
+ TIMx->EGR = TIM_PSCReloadMode;
+}
+
+/**
+ * @brief Specifies the TIMx Counter Mode to be used.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_CounterMode: specifies the Counter Mode to be used
+ * This parameter can be one of the following values:
+ * @arg TIM_CounterMode_Up: TIM Up Counting Mode
+ * @arg TIM_CounterMode_Down: TIM Down Counting Mode
+ * @arg TIM_CounterMode_CenterAligned1: TIM Center Aligned Mode1
+ * @arg TIM_CounterMode_CenterAligned2: TIM Center Aligned Mode2
+ * @arg TIM_CounterMode_CenterAligned3: TIM Center Aligned Mode3
+ * @retval None
+ */
+void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode)
+{
+ uint16_t tmpcr1 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_COUNTER_MODE(TIM_CounterMode));
+
+ tmpcr1 = TIMx->CR1;
+ /* Reset the CMS and DIR Bits */
+ tmpcr1 &= (uint16_t)(~((uint16_t)(TIM_CR1_DIR | TIM_CR1_CMS)));
+ /* Set the Counter Mode */
+ tmpcr1 |= TIM_CounterMode;
+ /* Write to TIMx CR1 register */
+ TIMx->CR1 = tmpcr1;
+}
+
+/**
+ * @brief Sets the TIMx Counter Register value
+ * @param TIMx: where x can be 1, 2, 6 to select the TIM
+ * peripheral.
+ * @param Counter: specifies the Counter register new value.
+ * @retval None
+ */
+void TIM_SetCounter(TIM_TypeDef* TIMx, uint32_t Counter)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+
+ /* Set the Counter Register value */
+ TIMx->CNT = Counter;
+}
+
+/**
+ * @brief Sets the TIMx Autoreload Register value
+ * @param TIMx: where x can be 1, 2, 6 to select the TIM peripheral.
+ * @param Autoreload: specifies the Autoreload register new value.
+ * @retval None
+ */
+void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint32_t Autoreload)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+
+ /* Set the Autoreload Register value */
+ TIMx->ARR = Autoreload;
+}
+
+/**
+ * @brief Gets the TIMx Counter value.
+ * @param TIMx: where x can be 1, 2, 6 to select the TIM
+ * peripheral.
+ * @retval Counter Register value.
+ */
+uint32_t TIM_GetCounter(TIM_TypeDef* TIMx)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+
+ /* Get the Counter Register value */
+ return TIMx->CNT;
+}
+
+/**
+ * @brief Gets the TIMx Prescaler value.
+ * @param TIMx: where x can be 1, 2, 6 to select the TIM
+ * peripheral.
+ * @retval Prescaler Register value.
+ */
+uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+
+ /* Get the Prescaler Register value */
+ return TIMx->PSC;
+}
+
+/**
+ * @brief Enables or Disables the TIMx Update event.
+ * @param TIMx: where x can be 1, 2, 6 to select the TIM
+ * peripheral.
+ * @param NewState: new state of the TIMx UDIS bit
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void TIM_UpdateDisableConfig(TIM_TypeDef* TIMx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Set the Update Disable Bit */
+ TIMx->CR1 |= TIM_CR1_UDIS;
+ }
+ else
+ {
+ /* Reset the Update Disable Bit */
+ TIMx->CR1 &= (uint16_t)~((uint16_t)TIM_CR1_UDIS);
+ }
+}
+
+/**
+ * @brief Configures the TIMx Update Request Interrupt source.
+ * @param TIMx: where x can be 1, 2, 6 to select the TIM
+ * peripheral.
+ * @param TIM_UpdateSource: specifies the Update source.
+ * This parameter can be one of the following values:
+ * @arg TIM_UpdateSource_Regular: Source of update is the counter
+ * overflow/underflow or the setting of UG bit, or an update
+ * generation through the slave mode controller.
+ * @arg TIM_UpdateSource_Global: Source of update is counter overflow/underflow.
+ * @retval None
+ */
+void TIM_UpdateRequestConfig(TIM_TypeDef* TIMx, uint16_t TIM_UpdateSource)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ assert_param(IS_TIM_UPDATE_SOURCE(TIM_UpdateSource));
+
+ if (TIM_UpdateSource != TIM_UpdateSource_Global)
+ {
+ /* Set the URS Bit */
+ TIMx->CR1 |= TIM_CR1_URS;
+ }
+ else
+ {
+ /* Reset the URS Bit */
+ TIMx->CR1 &= (uint16_t)~((uint16_t)TIM_CR1_URS);
+ }
+}
+
+/**
+ * @brief Enables or disables TIMx peripheral Preload register on ARR.
+ * @param TIMx: where x can be 1, 2, 6 to select the TIM
+ * peripheral.
+ * @param NewState: new state of the TIMx peripheral Preload register
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Set the ARR Preload Bit */
+ TIMx->CR1 |= TIM_CR1_ARPE;
+ }
+ else
+ {
+ /* Reset the ARR Preload Bit */
+ TIMx->CR1 &= (uint16_t)~((uint16_t)TIM_CR1_ARPE);
+ }
+}
+
+/**
+ * @brief Selects the TIMx's One Pulse Mode.
+ * @param TIMx: where x can be 1, 2, 6 to select the TIM
+ * peripheral.
+ * @param TIM_OPMode: specifies the OPM Mode to be used.
+ * This parameter can be one of the following values:
+ * @arg TIM_OPMode_Single
+ * @arg TIM_OPMode_Repetitive
+ * @retval None
+ */
+void TIM_SelectOnePulseMode(TIM_TypeDef* TIMx, uint16_t TIM_OPMode)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ assert_param(IS_TIM_OPM_MODE(TIM_OPMode));
+
+ /* Reset the OPM Bit */
+ TIMx->CR1 &= (uint16_t)~((uint16_t)TIM_CR1_OPM);
+ /* Configure the OPM Mode */
+ TIMx->CR1 |= TIM_OPMode;
+}
+
+/**
+ * @brief Sets the TIMx Clock Division value.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_CKD: specifies the clock division value.
+ * This parameter can be one of the following value:
+ * @arg TIM_CKD_DIV1: TDTS = Tck_tim
+ * @arg TIM_CKD_DIV2: TDTS = 2*Tck_tim
+ * @arg TIM_CKD_DIV4: TDTS = 4*Tck_tim
+ * @retval None
+ */
+void TIM_SetClockDivision(TIM_TypeDef* TIMx, uint16_t TIM_CKD)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST4_PERIPH(TIMx));
+ assert_param(IS_TIM_CKD_DIV(TIM_CKD));
+
+ /* Reset the CKD Bits */
+ TIMx->CR1 &= (uint16_t)~((uint16_t)TIM_CR1_CKD);
+ /* Set the CKD value */
+ TIMx->CR1 |= TIM_CKD;
+}
+
+/**
+ * @brief Enables or disables the specified TIM peripheral.
+ * @param TIMx: where x can be 1, 2, 6 to select the TIMx
+ * peripheral.
+ * @param NewState: new state of the TIMx peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the TIM Counter */
+ TIMx->CR1 |= TIM_CR1_CEN;
+ }
+ else
+ {
+ /* Disable the TIM Counter */
+ TIMx->CR1 &= (uint16_t)(~((uint16_t)TIM_CR1_CEN));
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Group2 Advanced-control timers (TIM1) specific features
+ * @brief Advanced-control timers (TIM1) specific features
+ *
+@verbatim
+ ===============================================================================
+ ##### Advanced-control timers (TIM1) specific features #####
+ ===============================================================================
+
+ ===================================================================
+ *** TIM Driver: how to use the Break feature ***
+ ===================================================================
+ [..] After configuring the Timer channel(s) in the appropriate Output Compare mode:
+
+ (#) Fill the TIM_BDTRInitStruct with the desired parameters for the Timer
+ Break Polarity, dead time, Lock level, the OSSI/OSSR State and the
+ AOE(automatic output enable).
+
+ (#) Call TIM_BDTRConfig(TIMx, &TIM_BDTRInitStruct) to configure the Timer
+
+ (#) Enable the Main Output using TIM_CtrlPWMOutputs(TIM1, ENABLE)
+
+ (#) Once the break even occurs, the Timer's output signals are put in reset
+ state or in a known state (according to the configuration made in
+ TIM_BDTRConfig() function).
+
+@endverbatim
+ * @{
+ */
+/**
+ * @brief Configures the: Break feature, dead time, Lock level, OSSI/OSSR State
+ * and the AOE(automatic output enable).
+ * @param TIMx: where x can be 1 to select the TIM
+ * @param TIM_BDTRInitStruct: pointer to a TIM_BDTRInitTypeDef structure that
+ * contains the BDTR Register configuration information for the TIM peripheral.
+ * @retval None
+ */
+void TIM_BDTRConfig(TIM_TypeDef* TIMx, TIM_BDTRInitTypeDef *TIM_BDTRInitStruct)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST2_PERIPH(TIMx));
+ assert_param(IS_TIM_OSSR_STATE(TIM_BDTRInitStruct->TIM_OSSRState));
+ assert_param(IS_TIM_OSSI_STATE(TIM_BDTRInitStruct->TIM_OSSIState));
+ assert_param(IS_TIM_LOCK_LEVEL(TIM_BDTRInitStruct->TIM_LOCKLevel));
+ assert_param(IS_TIM_BREAK_STATE(TIM_BDTRInitStruct->TIM_Break));
+ assert_param(IS_TIM_BREAK_POLARITY(TIM_BDTRInitStruct->TIM_BreakPolarity));
+ assert_param(IS_TIM_AUTOMATIC_OUTPUT_STATE(TIM_BDTRInitStruct->TIM_AutomaticOutput));
+ /* Set the Lock level, the Break enable Bit and the Ploarity, the OSSR State,
+ the OSSI State, the dead time value and the Automatic Output Enable Bit */
+ TIMx->BDTR = (uint32_t)TIM_BDTRInitStruct->TIM_OSSRState | TIM_BDTRInitStruct->TIM_OSSIState |
+ TIM_BDTRInitStruct->TIM_LOCKLevel | TIM_BDTRInitStruct->TIM_DeadTime |
+ TIM_BDTRInitStruct->TIM_Break | TIM_BDTRInitStruct->TIM_BreakPolarity |
+ TIM_BDTRInitStruct->TIM_AutomaticOutput;
+}
+
+/**
+ * @brief Fills each TIM_BDTRInitStruct member with its default value.
+ * @param TIM_BDTRInitStruct: pointer to a TIM_BDTRInitTypeDef structure which
+ * will be initialized.
+ * @retval None
+ */
+void TIM_BDTRStructInit(TIM_BDTRInitTypeDef* TIM_BDTRInitStruct)
+{
+ /* Set the default configuration */
+ TIM_BDTRInitStruct->TIM_OSSRState = TIM_OSSRState_Disable;
+ TIM_BDTRInitStruct->TIM_OSSIState = TIM_OSSIState_Disable;
+ TIM_BDTRInitStruct->TIM_LOCKLevel = TIM_LOCKLevel_OFF;
+ TIM_BDTRInitStruct->TIM_DeadTime = 0x00;
+ TIM_BDTRInitStruct->TIM_Break = TIM_Break_Disable;
+ TIM_BDTRInitStruct->TIM_BreakPolarity = TIM_BreakPolarity_Low;
+ TIM_BDTRInitStruct->TIM_AutomaticOutput = TIM_AutomaticOutput_Disable;
+}
+
+/**
+ * @brief Enables or disables the TIM peripheral Main Outputs.
+ * @param TIMx: where x can be 1 to select the TIMx peripheral.
+ * @param NewState: new state of the TIM peripheral Main Outputs.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST2_PERIPH(TIMx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the TIM Main Output */
+ TIMx->BDTR |= TIM_BDTR_MOE;
+ }
+ else
+ {
+ /* Disable the TIM Main Output */
+ TIMx->BDTR &= (uint16_t)(~((uint16_t)TIM_BDTR_MOE));
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Group3 Output Compare management functions
+ * @brief Output Compare management functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Output Compare management functions #####
+ ===============================================================================
+ *** TIM Driver: how to use it in Output Compare Mode ***
+ ===============================================================================
+ [..] To use the Timer in Output Compare mode, the following steps are mandatory:
+ (#) Enable TIM clock using
+ RCC_APBxPeriphClockCmd(RCC_APBxPeriph_TIMx, ENABLE) function.
+ (#) Configure the TIM pins by configuring the corresponding GPIO pins
+ (#) Configure the Time base unit as described in the first part of this
+ driver, if needed, else the Timer will run with the default
+ configuration:
+ (++) Autoreload value = 0xFFFF.
+ (++) Prescaler value = 0x0000.
+ (++) Counter mode = Up counting.
+ (++) Clock Division = TIM_CKD_DIV1.
+ (#) Fill the TIM_OCInitStruct with the desired parameters including:
+ (++) The TIM Output Compare mode: TIM_OCMode.
+ (++) TIM Output State: TIM_OutputState.
+ (++) TIM Pulse value: TIM_Pulse.
+ (++) TIM Output Compare Polarity : TIM_OCPolarity.
+ (#) Call TIM_OCxInit(TIMx, &TIM_OCInitStruct) to configure the desired
+ channel with the corresponding configuration.
+ (#) Call the TIM_Cmd(ENABLE) function to enable the TIM counter.
+ [..]
+ (@) All other functions can be used separately to modify, if needed,
+ a specific feature of the Timer.
+ (@) In case of PWM mode, this function is mandatory:
+ TIM_OCxPreloadConfig(TIMx, TIM_OCPreload_ENABLE).
+ (@) If the corresponding interrupt or DMA request are needed, the user should:
+ (#@) Enable the NVIC (or the DMA) to use the TIM interrupts (or DMA requests).
+ (#@) Enable the corresponding interrupt (or DMA request) using the function
+ TIM_ITConfig(TIMx, TIM_IT_CCx) (or TIM_DMA_Cmd(TIMx, TIM_DMA_CCx)).
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the TIMx Channel1 according to the specified
+ * parameters in the TIM_OCInitStruct.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure
+ * that contains the configuration information for the specified TIM
+ * peripheral.
+ * @retval None
+ */
+void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct)
+{
+ uint16_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST4_PERIPH(TIMx));
+ assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode));
+ assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState));
+ assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity));
+ /* Disable the Channel 1: Reset the CC1E Bit */
+ TIMx->CCER &= (uint16_t)(~(uint16_t)TIM_CCER_CC1E);
+ /* Get the TIMx CCER register value */
+ tmpccer = TIMx->CCER;
+ /* Get the TIMx CR2 register value */
+ tmpcr2 = TIMx->CR2;
+
+ /* Get the TIMx CCMR1 register value */
+ tmpccmrx = TIMx->CCMR1;
+
+ /* Reset the Output Compare Mode Bits */
+ tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR1_OC1M));
+ tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR1_CC1S));
+
+ /* Select the Output Compare Mode */
+ tmpccmrx |= TIM_OCInitStruct->TIM_OCMode;
+
+ /* Reset the Output Polarity level */
+ tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC1P));
+ /* Set the Output Compare Polarity */
+ tmpccer |= TIM_OCInitStruct->TIM_OCPolarity;
+
+ /* Set the Output State */
+ tmpccer |= TIM_OCInitStruct->TIM_OutputState;
+
+ if(TIMx == TIM1)
+ {
+ assert_param(IS_TIM_OUTPUTN_STATE(TIM_OCInitStruct->TIM_OutputNState));
+ assert_param(IS_TIM_OCN_POLARITY(TIM_OCInitStruct->TIM_OCNPolarity));
+ assert_param(IS_TIM_OCNIDLE_STATE(TIM_OCInitStruct->TIM_OCNIdleState));
+ assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState));
+
+ /* Reset the Output N Polarity level */
+ tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC1NP));
+ /* Set the Output N Polarity */
+ tmpccer |= TIM_OCInitStruct->TIM_OCNPolarity;
+
+ /* Reset the Output N State */
+ tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC1NE));
+ /* Set the Output N State */
+ tmpccer |= TIM_OCInitStruct->TIM_OutputNState;
+
+ /* Reset the Ouput Compare and Output Compare N IDLE State */
+ tmpcr2 &= (uint16_t)(~((uint16_t)TIM_CR2_OIS1));
+ tmpcr2 &= (uint16_t)(~((uint16_t)TIM_CR2_OIS1N));
+
+ /* Set the Output Idle state */
+ tmpcr2 |= TIM_OCInitStruct->TIM_OCIdleState;
+ /* Set the Output N Idle state */
+ tmpcr2 |= TIM_OCInitStruct->TIM_OCNIdleState;
+ }
+ /* Write to TIMx CR2 */
+ TIMx->CR2 = tmpcr2;
+
+ /* Write to TIMx CCMR1 */
+ TIMx->CCMR1 = tmpccmrx;
+
+ /* Set the Capture Compare Register value */
+ TIMx->CCR1 = TIM_OCInitStruct->TIM_Pulse;
+
+ /* Write to TIMx CCER */
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Initializes the TIMx Channel2 according to the specified
+ * parameters in the TIM_OCInitStruct.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure
+ * that contains the configuration information for the specified TIM
+ * peripheral.
+ * @retval None
+ */
+void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct)
+{
+ uint16_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+ assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode));
+ assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState));
+ assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity));
+ /* Disable the Channel 2: Reset the CC2E Bit */
+ TIMx->CCER &= (uint16_t)(~((uint16_t)TIM_CCER_CC2E));
+
+ /* Get the TIMx CCER register value */
+ tmpccer = TIMx->CCER;
+ /* Get the TIMx CR2 register value */
+ tmpcr2 = TIMx->CR2;
+
+ /* Get the TIMx CCMR1 register value */
+ tmpccmrx = TIMx->CCMR1;
+
+ /* Reset the Output Compare mode and Capture/Compare selection Bits */
+ tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR1_OC2M));
+ tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR1_CC2S));
+
+ /* Select the Output Compare Mode */
+ tmpccmrx |= (uint16_t)(TIM_OCInitStruct->TIM_OCMode << 8);
+
+ /* Reset the Output Polarity level */
+ tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC2P));
+ /* Set the Output Compare Polarity */
+ tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCPolarity << 4);
+
+ /* Set the Output State */
+ tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputState << 4);
+
+ if(TIMx == TIM1)
+ {
+ /* Check the parameters */
+ assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState));
+
+ /* Reset the Ouput Compare State */
+ tmpcr2 &= (uint16_t)(~((uint16_t)TIM_CR2_OIS2));
+
+ /* Set the Output Idle state */
+ tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCIdleState << 2);
+
+ if (TIMx == TIM1)
+ {
+ /* Check the parameters */
+ assert_param(IS_TIM_OUTPUTN_STATE(TIM_OCInitStruct->TIM_OutputNState));
+ assert_param(IS_TIM_OCN_POLARITY(TIM_OCInitStruct->TIM_OCNPolarity));
+ assert_param(IS_TIM_OCNIDLE_STATE(TIM_OCInitStruct->TIM_OCNIdleState));
+
+ /* Reset the Output N Polarity level */
+ tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC2NP));
+ /* Set the Output N Polarity */
+ tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCNPolarity << 4);
+
+ /* Reset the Output N State */
+ tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC2NE));
+ /* Set the Output N State */
+ tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputNState << 4);
+
+ /* Reset the Output Compare N IDLE State */
+ tmpcr2 &= (uint16_t)(~((uint16_t)TIM_CR2_OIS2N));
+
+ /* Set the Output N Idle state */
+ tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCNIdleState << 2);
+ }
+ }
+ /* Write to TIMx CR2 */
+ TIMx->CR2 = tmpcr2;
+
+ /* Write to TIMx CCMR1 */
+ TIMx->CCMR1 = tmpccmrx;
+
+ /* Set the Capture Compare Register value */
+ TIMx->CCR2 = TIM_OCInitStruct->TIM_Pulse;
+
+ /* Write to TIMx CCER */
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Initializes the TIMx Channel3 according to the specified
+ * parameters in the TIM_OCInitStruct.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure
+ * that contains the configuration information for the specified TIM
+ * peripheral.
+ * @retval None
+ */
+void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct)
+{
+ uint16_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode));
+ assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState));
+ assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity));
+ /* Disable the Channel 2: Reset the CC2E Bit */
+ TIMx->CCER &= (uint16_t)(~((uint16_t)TIM_CCER_CC3E));
+
+ /* Get the TIMx CCER register value */
+ tmpccer = TIMx->CCER;
+ /* Get the TIMx CR2 register value */
+ tmpcr2 = TIMx->CR2;
+
+ /* Get the TIMx CCMR2 register value */
+ tmpccmrx = TIMx->CCMR2;
+
+ /* Reset the Output Compare mode and Capture/Compare selection Bits */
+ tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR2_OC3M));
+ tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR2_CC3S));
+ /* Select the Output Compare Mode */
+ tmpccmrx |= TIM_OCInitStruct->TIM_OCMode;
+
+ /* Reset the Output Polarity level */
+ tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC3P));
+ /* Set the Output Compare Polarity */
+ tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCPolarity << 8);
+
+ /* Set the Output State */
+ tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputState << 8);
+
+ if(TIMx == TIM1)
+ {
+ assert_param(IS_TIM_OUTPUTN_STATE(TIM_OCInitStruct->TIM_OutputNState));
+ assert_param(IS_TIM_OCN_POLARITY(TIM_OCInitStruct->TIM_OCNPolarity));
+ assert_param(IS_TIM_OCNIDLE_STATE(TIM_OCInitStruct->TIM_OCNIdleState));
+ assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState));
+
+ /* Reset the Output N Polarity level */
+ tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC3NP));
+ /* Set the Output N Polarity */
+ tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCNPolarity << 8);
+ /* Reset the Output N State */
+ tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC3NE));
+
+ /* Set the Output N State */
+ tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputNState << 8);
+ /* Reset the Ouput Compare and Output Compare N IDLE State */
+ tmpcr2 &= (uint16_t)(~((uint16_t)TIM_CR2_OIS3));
+ tmpcr2 &= (uint16_t)(~((uint16_t)TIM_CR2_OIS3N));
+ /* Set the Output Idle state */
+ tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCIdleState << 4);
+ /* Set the Output N Idle state */
+ tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCNIdleState << 4);
+ }
+ /* Write to TIMx CR2 */
+ TIMx->CR2 = tmpcr2;
+
+ /* Write to TIMx CCMR2 */
+ TIMx->CCMR2 = tmpccmrx;
+
+ /* Set the Capture Compare Register value */
+ TIMx->CCR3 = TIM_OCInitStruct->TIM_Pulse;
+
+ /* Write to TIMx CCER */
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Initializes the TIMx Channel4 according to the specified
+ * parameters in the TIM_OCInitStruct.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure
+ * that contains the configuration information for the specified TIM
+ * peripheral.
+ * @retval None
+ */
+void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct)
+{
+ uint16_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode));
+ assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState));
+ assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity));
+ /* Disable the Channel 2: Reset the CC4E Bit */
+ TIMx->CCER &= (uint16_t)(~((uint16_t)TIM_CCER_CC4E));
+
+ /* Get the TIMx CCER register value */
+ tmpccer = TIMx->CCER;
+ /* Get the TIMx CR2 register value */
+ tmpcr2 = TIMx->CR2;
+
+ /* Get the TIMx CCMR2 register value */
+ tmpccmrx = TIMx->CCMR2;
+
+ /* Reset the Output Compare mode and Capture/Compare selection Bits */
+ tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR2_OC4M));
+ tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR2_CC4S));
+
+ /* Select the Output Compare Mode */
+ tmpccmrx |= (uint16_t)(TIM_OCInitStruct->TIM_OCMode << 8);
+
+ /* Reset the Output Polarity level */
+ tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC4P));
+ /* Set the Output Compare Polarity */
+ tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCPolarity << 12);
+
+ /* Set the Output State */
+ tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputState << 12);
+
+ if(TIMx == TIM1)
+ {
+ assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState));
+ /* Reset the Ouput Compare IDLE State */
+ tmpcr2 &= (uint16_t)(~((uint16_t)TIM_CR2_OIS4));
+ /* Set the Output Idle state */
+ tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCIdleState << 6);
+ }
+ /* Write to TIMx CR2 */
+ TIMx->CR2 = tmpcr2;
+
+ /* Write to TIMx CCMR2 */
+ TIMx->CCMR2 = tmpccmrx;
+
+ /* Set the Capture Compare Register value */
+ TIMx->CCR4 = TIM_OCInitStruct->TIM_Pulse;
+
+ /* Write to TIMx CCER */
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Fills each TIM_OCInitStruct member with its default value.
+ * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure which will
+ * be initialized.
+ * @retval None
+ */
+void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct)
+{
+ /* Set the default configuration */
+ TIM_OCInitStruct->TIM_OCMode = TIM_OCMode_Timing;
+ TIM_OCInitStruct->TIM_OutputState = TIM_OutputState_Disable;
+ TIM_OCInitStruct->TIM_OutputNState = TIM_OutputNState_Disable;
+ TIM_OCInitStruct->TIM_Pulse = 0x0000000;
+ TIM_OCInitStruct->TIM_OCPolarity = TIM_OCPolarity_High;
+ TIM_OCInitStruct->TIM_OCNPolarity = TIM_OCPolarity_High;
+ TIM_OCInitStruct->TIM_OCIdleState = TIM_OCIdleState_Reset;
+ TIM_OCInitStruct->TIM_OCNIdleState = TIM_OCNIdleState_Reset;
+}
+
+/**
+ * @brief Selects the TIM Output Compare Mode.
+ * @note This function disables the selected channel before changing the Output
+ * Compare Mode.
+ * User has to enable this channel using TIM_CCxCmd and TIM_CCxNCmd functions.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_Channel: specifies the TIM Channel
+ * This parameter can be one of the following values:
+ * @arg TIM_Channel_1: TIM Channel 1
+ * @arg TIM_Channel_2: TIM Channel 2
+ * @arg TIM_Channel_3: TIM Channel 3
+ * @arg TIM_Channel_4: TIM Channel 4
+ * @param TIM_OCMode: specifies the TIM Output Compare Mode.
+ * This parameter can be one of the following values:
+ * @arg TIM_OCMode_Timing
+ * @arg TIM_OCMode_Active
+ * @arg TIM_OCMode_Toggle
+ * @arg TIM_OCMode_PWM1
+ * @arg TIM_OCMode_PWM2
+ * @arg TIM_ForcedAction_Active
+ * @arg TIM_ForcedAction_InActive
+ * @retval None
+ */
+void TIM_SelectOCxM(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode)
+{
+ uint32_t tmp = 0;
+ uint16_t tmp1 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST4_PERIPH(TIMx));
+ assert_param(IS_TIM_OCM(TIM_OCMode));
+
+ tmp = (uint32_t) TIMx;
+ tmp += CCMR_OFFSET;
+
+ tmp1 = CCER_CCE_SET << (uint16_t)TIM_Channel;
+
+ /* Disable the Channel: Reset the CCxE Bit */
+ TIMx->CCER &= (uint16_t) ~tmp1;
+
+ if((TIM_Channel == TIM_Channel_1) ||(TIM_Channel == TIM_Channel_3))
+ {
+ tmp += (TIM_Channel>>1);
+
+ /* Reset the OCxM bits in the CCMRx register */
+ *(__IO uint32_t *) tmp &= (uint32_t)~((uint32_t)TIM_CCMR1_OC1M);
+
+ /* Configure the OCxM bits in the CCMRx register */
+ *(__IO uint32_t *) tmp |= TIM_OCMode;
+ }
+ else
+ {
+ tmp += (uint16_t)(TIM_Channel - (uint16_t)4)>> (uint16_t)1;
+
+ /* Reset the OCxM bits in the CCMRx register */
+ *(__IO uint32_t *) tmp &= (uint32_t)~((uint32_t)TIM_CCMR1_OC2M);
+
+ /* Configure the OCxM bits in the CCMRx register */
+ *(__IO uint32_t *) tmp |= (uint16_t)(TIM_OCMode << 8);
+ }
+}
+
+/**
+ * @brief Sets the TIMx Capture Compare1 Register value
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param Compare1: specifies the Capture Compare1 register new value.
+ * @retval None
+ */
+void TIM_SetCompare1(TIM_TypeDef* TIMx, uint32_t Compare1)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST4_PERIPH(TIMx));
+
+ /* Set the Capture Compare1 Register value */
+ TIMx->CCR1 = Compare1;
+}
+
+/**
+ * @brief Sets the TIMx Capture Compare2 Register value
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param Compare2: specifies the Capture Compare2 register new value.
+ * @retval None
+ */
+void TIM_SetCompare2(TIM_TypeDef* TIMx, uint32_t Compare2)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+
+ /* Set the Capture Compare2 Register value */
+ TIMx->CCR2 = Compare2;
+}
+
+/**
+ * @brief Sets the TIMx Capture Compare3 Register value
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param Compare3: specifies the Capture Compare3 register new value.
+ * @retval None
+ */
+void TIM_SetCompare3(TIM_TypeDef* TIMx, uint32_t Compare3)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+
+ /* Set the Capture Compare3 Register value */
+ TIMx->CCR3 = Compare3;
+}
+
+/**
+ * @brief Sets the TIMx Capture Compare4 Register value
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param Compare4: specifies the Capture Compare4 register new value.
+ * @retval None
+ */
+void TIM_SetCompare4(TIM_TypeDef* TIMx, uint32_t Compare4)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+
+ /* Set the Capture Compare4 Register value */
+ TIMx->CCR4 = Compare4;
+}
+
+/**
+ * @brief Forces the TIMx output 1 waveform to active or inactive level.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform.
+ * This parameter can be one of the following values:
+ * @arg TIM_ForcedAction_Active: Force active level on OC1REF
+ * @arg TIM_ForcedAction_InActive: Force inactive level on OC1REF.
+ * @retval None
+ */
+void TIM_ForcedOC1Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction)
+{
+ uint16_t tmpccmr1 = 0;
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST4_PERIPH(TIMx));
+ assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction));
+ tmpccmr1 = TIMx->CCMR1;
+ /* Reset the OC1M Bits */
+ tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC1M);
+ /* Configure The Forced output Mode */
+ tmpccmr1 |= TIM_ForcedAction;
+ /* Write to TIMx CCMR1 register */
+ TIMx->CCMR1 = tmpccmr1;
+}
+
+/**
+ * @brief Forces the TIMx output 2 waveform to active or inactive level.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform.
+ * This parameter can be one of the following values:
+ * @arg TIM_ForcedAction_Active: Force active level on OC2REF
+ * @arg TIM_ForcedAction_InActive: Force inactive level on OC2REF.
+ * @retval None
+ */
+void TIM_ForcedOC2Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction)
+{
+ uint16_t tmpccmr1 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+ assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction));
+
+ tmpccmr1 = TIMx->CCMR1;
+ /* Reset the OC2M Bits */
+ tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC2M);
+ /* Configure The Forced output Mode */
+ tmpccmr1 |= (uint16_t)(TIM_ForcedAction << 8);
+ /* Write to TIMx CCMR1 register */
+ TIMx->CCMR1 = tmpccmr1;
+}
+
+/**
+ * @brief Forces the TIMx output 3 waveform to active or inactive level.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform.
+ * This parameter can be one of the following values:
+ * @arg TIM_ForcedAction_Active: Force active level on OC3REF
+ * @arg TIM_ForcedAction_InActive: Force inactive level on OC3REF.
+ * @retval None
+ */
+void TIM_ForcedOC3Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction)
+{
+ uint16_t tmpccmr2 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction));
+
+ tmpccmr2 = TIMx->CCMR2;
+ /* Reset the OC1M Bits */
+ tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC3M);
+ /* Configure The Forced output Mode */
+ tmpccmr2 |= TIM_ForcedAction;
+ /* Write to TIMx CCMR2 register */
+ TIMx->CCMR2 = tmpccmr2;
+}
+
+/**
+ * @brief Forces the TIMx output 4 waveform to active or inactive level.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform.
+ * This parameter can be one of the following values:
+ * @arg TIM_ForcedAction_Active: Force active level on OC4REF
+ * @arg TIM_ForcedAction_InActive: Force inactive level on OC4REF.
+ * @retval None
+ */
+void TIM_ForcedOC4Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction)
+{
+ uint16_t tmpccmr2 = 0;
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction));
+
+ tmpccmr2 = TIMx->CCMR2;
+ /* Reset the OC2M Bits */
+ tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC4M);
+ /* Configure The Forced output Mode */
+ tmpccmr2 |= (uint16_t)(TIM_ForcedAction << 8);
+ /* Write to TIMx CCMR2 register */
+ TIMx->CCMR2 = tmpccmr2;
+}
+
+/**
+ * @brief Sets or Resets the TIM peripheral Capture Compare Preload Control bit.
+ * @param TIMx: where x can be 1, 2 to select the TIMx peripheral
+ * @param NewState: new state of the Capture Compare Preload Control bit
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void TIM_CCPreloadControl(TIM_TypeDef* TIMx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Set the CCPC Bit */
+ TIMx->CR2 |= TIM_CR2_CCPC;
+ }
+ else
+ {
+ /* Reset the CCPC Bit */
+ TIMx->CR2 &= (uint16_t)~((uint16_t)TIM_CR2_CCPC);
+ }
+}
+
+
+/**
+ * @brief Enables or disables the TIMx peripheral Preload register on CCR1.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_OCPreload: new state of the TIMx peripheral Preload register
+ * This parameter can be one of the following values:
+ * @arg TIM_OCPreload_Enable
+ * @arg TIM_OCPreload_Disable
+ * @retval None
+ */
+void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload)
+{
+ uint16_t tmpccmr1 = 0;
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST4_PERIPH(TIMx));
+ assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload));
+
+ tmpccmr1 = TIMx->CCMR1;
+ /* Reset the OC1PE Bit */
+ tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC1PE);
+ /* Enable or Disable the Output Compare Preload feature */
+ tmpccmr1 |= TIM_OCPreload;
+ /* Write to TIMx CCMR1 register */
+ TIMx->CCMR1 = tmpccmr1;
+}
+
+/**
+ * @brief Enables or disables the TIMx peripheral Preload register on CCR2.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_OCPreload: new state of the TIMx peripheral Preload register
+ * This parameter can be one of the following values:
+ * @arg TIM_OCPreload_Enable
+ * @arg TIM_OCPreload_Disable
+ * @retval None
+ */
+void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload)
+{
+ uint16_t tmpccmr1 = 0;
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+ assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload));
+
+ tmpccmr1 = TIMx->CCMR1;
+ /* Reset the OC2PE Bit */
+ tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC2PE);
+ /* Enable or Disable the Output Compare Preload feature */
+ tmpccmr1 |= (uint16_t)(TIM_OCPreload << 8);
+ /* Write to TIMx CCMR1 register */
+ TIMx->CCMR1 = tmpccmr1;
+}
+
+/**
+ * @brief Enables or disables the TIMx peripheral Preload register on CCR3.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_OCPreload: new state of the TIMx peripheral Preload register
+ * This parameter can be one of the following values:
+ * @arg TIM_OCPreload_Enable
+ * @arg TIM_OCPreload_Disable
+ * @retval None
+ */
+void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload)
+{
+ uint16_t tmpccmr2 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload));
+
+ tmpccmr2 = TIMx->CCMR2;
+ /* Reset the OC3PE Bit */
+ tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC3PE);
+ /* Enable or Disable the Output Compare Preload feature */
+ tmpccmr2 |= TIM_OCPreload;
+ /* Write to TIMx CCMR2 register */
+ TIMx->CCMR2 = tmpccmr2;
+}
+
+/**
+ * @brief Enables or disables the TIMx peripheral Preload register on CCR4.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_OCPreload: new state of the TIMx peripheral Preload register
+ * This parameter can be one of the following values:
+ * @arg TIM_OCPreload_Enable
+ * @arg TIM_OCPreload_Disable
+ * @retval None
+ */
+void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload)
+{
+ uint16_t tmpccmr2 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload));
+
+ tmpccmr2 = TIMx->CCMR2;
+ /* Reset the OC4PE Bit */
+ tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC4PE);
+ /* Enable or Disable the Output Compare Preload feature */
+ tmpccmr2 |= (uint16_t)(TIM_OCPreload << 8);
+ /* Write to TIMx CCMR2 register */
+ TIMx->CCMR2 = tmpccmr2;
+}
+
+/**
+ * @brief Configures the TIMx Output Compare 1 Fast feature.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit.
+ * This parameter can be one of the following values:
+ * @arg TIM_OCFast_Enable: TIM output compare fast enable
+ * @arg TIM_OCFast_Disable: TIM output compare fast disable
+ * @retval None
+ */
+void TIM_OC1FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast)
+{
+ uint16_t tmpccmr1 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST4_PERIPH(TIMx));
+ assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast));
+
+ /* Get the TIMx CCMR1 register value */
+ tmpccmr1 = TIMx->CCMR1;
+ /* Reset the OC1FE Bit */
+ tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC1FE);
+ /* Enable or Disable the Output Compare Fast Bit */
+ tmpccmr1 |= TIM_OCFast;
+ /* Write to TIMx CCMR1 */
+ TIMx->CCMR1 = tmpccmr1;
+}
+
+/**
+ * @brief Configures the TIMx Output Compare 2 Fast feature.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit.
+ * This parameter can be one of the following values:
+ * @arg TIM_OCFast_Enable: TIM output compare fast enable
+ * @arg TIM_OCFast_Disable: TIM output compare fast disable
+ * @retval None
+ */
+void TIM_OC2FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast)
+{
+ uint16_t tmpccmr1 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+ assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast));
+
+ /* Get the TIMx CCMR1 register value */
+ tmpccmr1 = TIMx->CCMR1;
+ /* Reset the OC2FE Bit */
+ tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC2FE);
+ /* Enable or Disable the Output Compare Fast Bit */
+ tmpccmr1 |= (uint16_t)(TIM_OCFast << 8);
+ /* Write to TIMx CCMR1 */
+ TIMx->CCMR1 = tmpccmr1;
+}
+
+/**
+ * @brief Configures the TIMx Output Compare 3 Fast feature.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit.
+ * This parameter can be one of the following values:
+ * @arg TIM_OCFast_Enable: TIM output compare fast enable
+ * @arg TIM_OCFast_Disable: TIM output compare fast disable
+ * @retval None
+ */
+void TIM_OC3FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast)
+{
+ uint16_t tmpccmr2 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast));
+
+ /* Get the TIMx CCMR2 register value */
+ tmpccmr2 = TIMx->CCMR2;
+ /* Reset the OC3FE Bit */
+ tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC3FE);
+ /* Enable or Disable the Output Compare Fast Bit */
+ tmpccmr2 |= TIM_OCFast;
+ /* Write to TIMx CCMR2 */
+ TIMx->CCMR2 = tmpccmr2;
+}
+
+/**
+ * @brief Configures the TIMx Output Compare 4 Fast feature.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit.
+ * This parameter can be one of the following values:
+ * @arg TIM_OCFast_Enable: TIM output compare fast enable
+ * @arg TIM_OCFast_Disable: TIM output compare fast disable
+ * @retval None
+ */
+void TIM_OC4FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast)
+{
+ uint16_t tmpccmr2 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast));
+
+ /* Get the TIMx CCMR2 register value */
+ tmpccmr2 = TIMx->CCMR2;
+ /* Reset the OC4FE Bit */
+ tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC4FE);
+ /* Enable or Disable the Output Compare Fast Bit */
+ tmpccmr2 |= (uint16_t)(TIM_OCFast << 8);
+ /* Write to TIMx CCMR2 */
+ TIMx->CCMR2 = tmpccmr2;
+}
+
+/**
+ * @brief Clears or safeguards the OCREF1 signal on an external event
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit.
+ * This parameter can be one of the following values:
+ * @arg TIM_OCClear_Enable: TIM Output clear enable
+ * @arg TIM_OCClear_Disable: TIM Output clear disable
+ * @retval None
+ */
+void TIM_ClearOC1Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear)
+{
+ uint16_t tmpccmr1 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST4_PERIPH(TIMx));
+ assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear));
+
+ tmpccmr1 = TIMx->CCMR1;
+ /* Reset the OC1CE Bit */
+ tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC1CE);
+ /* Enable or Disable the Output Compare Clear Bit */
+ tmpccmr1 |= TIM_OCClear;
+ /* Write to TIMx CCMR1 register */
+ TIMx->CCMR1 = tmpccmr1;
+}
+
+/**
+ * @brief Clears or safeguards the OCREF2 signal on an external event
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit.
+ * This parameter can be one of the following values:
+ * @arg TIM_OCClear_Enable: TIM Output clear enable
+ * @arg TIM_OCClear_Disable: TIM Output clear disable
+ * @retval None
+ */
+void TIM_ClearOC2Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear)
+{
+ uint16_t tmpccmr1 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+ assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear));
+
+ tmpccmr1 = TIMx->CCMR1;
+ /* Reset the OC2CE Bit */
+ tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC2CE);
+ /* Enable or Disable the Output Compare Clear Bit */
+ tmpccmr1 |= (uint16_t)(TIM_OCClear << 8);
+ /* Write to TIMx CCMR1 register */
+ TIMx->CCMR1 = tmpccmr1;
+}
+
+/**
+ * @brief Clears or safeguards the OCREF3 signal on an external event
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit.
+ * This parameter can be one of the following values:
+ * @arg TIM_OCClear_Enable: TIM Output clear enable
+ * @arg TIM_OCClear_Disable: TIM Output clear disable
+ * @retval None
+ */
+void TIM_ClearOC3Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear)
+{
+ uint16_t tmpccmr2 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear));
+
+ tmpccmr2 = TIMx->CCMR2;
+ /* Reset the OC3CE Bit */
+ tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC3CE);
+ /* Enable or Disable the Output Compare Clear Bit */
+ tmpccmr2 |= TIM_OCClear;
+ /* Write to TIMx CCMR2 register */
+ TIMx->CCMR2 = tmpccmr2;
+}
+
+/**
+ * @brief Clears or safeguards the OCREF4 signal on an external event
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit.
+ * This parameter can be one of the following values:
+ * @arg TIM_OCClear_Enable: TIM Output clear enable
+ * @arg TIM_OCClear_Disable: TIM Output clear disable
+ * @retval None
+ */
+void TIM_ClearOC4Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear)
+{
+ uint16_t tmpccmr2 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear));
+
+ tmpccmr2 = TIMx->CCMR2;
+ /* Reset the OC4CE Bit */
+ tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC4CE);
+ /* Enable or Disable the Output Compare Clear Bit */
+ tmpccmr2 |= (uint16_t)(TIM_OCClear << 8);
+ /* Write to TIMx CCMR2 register */
+ TIMx->CCMR2 = tmpccmr2;
+}
+
+/**
+ * @brief Configures the TIMx channel 1 polarity.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_OCPolarity: specifies the OC1 Polarity
+ * This parmeter can be one of the following values:
+ * @arg TIM_OCPolarity_High: Output Compare active high
+ * @arg TIM_OCPolarity_Low: Output Compare active low
+ * @retval None
+ */
+void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity)
+{
+ uint16_t tmpccer = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST4_PERIPH(TIMx));
+ assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity));
+
+ tmpccer = TIMx->CCER;
+ /* Set or Reset the CC1P Bit */
+ tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC1P);
+ tmpccer |= TIM_OCPolarity;
+ /* Write to TIMx CCER register */
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Configures the TIMx Channel 1N polarity.
+ * @param TIMx: where x can be 1 to select the TIM peripheral.
+ * @param TIM_OCNPolarity: specifies the OC1N Polarity
+ * This parmeter can be one of the following values:
+ * @arg TIM_OCNPolarity_High: Output Compare active high
+ * @arg TIM_OCNPolarity_Low: Output Compare active low
+ * @retval None
+ */
+void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity)
+{
+ uint16_t tmpccer = 0;
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST2_PERIPH(TIMx));
+ assert_param(IS_TIM_OCN_POLARITY(TIM_OCNPolarity));
+
+ tmpccer = TIMx->CCER;
+ /* Set or Reset the CC1NP Bit */
+ tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC1NP);
+ tmpccer |= TIM_OCNPolarity;
+ /* Write to TIMx CCER register */
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Configures the TIMx channel 2 polarity.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_OCPolarity: specifies the OC2 Polarity
+ * This parmeter can be one of the following values:
+ * @arg TIM_OCPolarity_High: Output Compare active high
+ * @arg TIM_OCPolarity_Low: Output Compare active low
+ * @retval None
+ */
+void TIM_OC2PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity)
+{
+ uint16_t tmpccer = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+ assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity));
+
+ tmpccer = TIMx->CCER;
+ /* Set or Reset the CC2P Bit */
+ tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC2P);
+ tmpccer |= (uint16_t)(TIM_OCPolarity << 4);
+ /* Write to TIMx CCER register */
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Configures the TIMx Channel 2N polarity.
+ * @param TIMx: where x can be 1 to select the TIM peripheral.
+ * @param TIM_OCNPolarity: specifies the OC2N Polarity
+ * This parmeter can be one of the following values:
+ * @arg TIM_OCNPolarity_High: Output Compare active high
+ * @arg TIM_OCNPolarity_Low: Output Compare active low
+ * @retval None
+ */
+void TIM_OC2NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity)
+{
+ uint16_t tmpccer = 0;
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST1_PERIPH(TIMx));
+ assert_param(IS_TIM_OCN_POLARITY(TIM_OCNPolarity));
+
+ tmpccer = TIMx->CCER;
+ /* Set or Reset the CC2NP Bit */
+ tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC2NP);
+ tmpccer |= (uint16_t)(TIM_OCNPolarity << 4);
+ /* Write to TIMx CCER register */
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Configures the TIMx channel 3 polarity.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_OCPolarity: specifies the OC3 Polarity
+ * This parmeter can be one of the following values:
+ * @arg TIM_OCPolarity_High: Output Compare active high
+ * @arg TIM_OCPolarity_Low: Output Compare active low
+ * @retval None
+ */
+void TIM_OC3PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity)
+{
+ uint16_t tmpccer = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity));
+
+ tmpccer = TIMx->CCER;
+ /* Set or Reset the CC3P Bit */
+ tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC3P);
+ tmpccer |= (uint16_t)(TIM_OCPolarity << 8);
+ /* Write to TIMx CCER register */
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Configures the TIMx Channel 3N polarity.
+ * @param TIMx: where x can be 1 to select the TIM peripheral.
+ * @param TIM_OCNPolarity: specifies the OC3N Polarity
+ * This parmeter can be one of the following values:
+ * @arg TIM_OCNPolarity_High: Output Compare active high
+ * @arg TIM_OCNPolarity_Low: Output Compare active low
+ * @retval None
+ */
+void TIM_OC3NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity)
+{
+ uint16_t tmpccer = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST1_PERIPH(TIMx));
+ assert_param(IS_TIM_OCN_POLARITY(TIM_OCNPolarity));
+
+ tmpccer = TIMx->CCER;
+ /* Set or Reset the CC3NP Bit */
+ tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC3NP);
+ tmpccer |= (uint16_t)(TIM_OCNPolarity << 8);
+ /* Write to TIMx CCER register */
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Configures the TIMx channel 4 polarity.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_OCPolarity: specifies the OC4 Polarity
+ * This parmeter can be one of the following values:
+ * @arg TIM_OCPolarity_High: Output Compare active high
+ * @arg TIM_OCPolarity_Low: Output Compare active low
+ * @retval None
+ */
+void TIM_OC4PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity)
+{
+ uint16_t tmpccer = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity));
+
+ tmpccer = TIMx->CCER;
+ /* Set or Reset the CC4P Bit */
+ tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC4P);
+ tmpccer |= (uint16_t)(TIM_OCPolarity << 12);
+ /* Write to TIMx CCER register */
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Selects the OCReference Clear source.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_OCReferenceClear: specifies the OCReference Clear source.
+ * This parameter can be one of the following values:
+ * @arg TIM_OCReferenceClear_ETRF: The internal OCreference clear input is connected to ETRF.
+ * @arg TIM_OCReferenceClear_OCREFCLR: The internal OCreference clear input is connected to OCREF_CLR input.
+ * @retval None
+ */
+void TIM_SelectOCREFClear(TIM_TypeDef* TIMx, uint16_t TIM_OCReferenceClear)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(TIM_OCREFERENCECECLEAR_SOURCE(TIM_OCReferenceClear));
+
+ /* Set the TIM_OCReferenceClear source */
+ TIMx->SMCR &= (uint16_t)~((uint16_t)TIM_SMCR_OCCS);
+ TIMx->SMCR |= TIM_OCReferenceClear;
+}
+
+/**
+ * @brief Enables or disables the TIM Capture Compare Channel x.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_Channel: specifies the TIM Channel
+ * This parameter can be one of the following values:
+ * @arg TIM_Channel_1: TIM Channel 1
+ * @arg TIM_Channel_2: TIM Channel 2
+ * @arg TIM_Channel_3: TIM Channel 3
+ * @arg TIM_Channel_4: TIM Channel 4
+ * @param TIM_CCx: specifies the TIM Channel CCxE bit new state.
+ * This parameter can be: TIM_CCx_Enable or TIM_CCx_Disable.
+ * @retval None
+ */
+void TIM_CCxCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCx)
+{
+ uint16_t tmp = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST4_PERIPH(TIMx));
+ assert_param(IS_TIM_CCX(TIM_CCx));
+
+ tmp = CCER_CCE_SET << TIM_Channel;
+
+ /* Reset the CCxE Bit */
+ TIMx->CCER &= (uint16_t)~ tmp;
+
+ /* Set or reset the CCxE Bit */
+ TIMx->CCER |= (uint16_t)(TIM_CCx << TIM_Channel);
+}
+
+/**
+ * @brief Enables or disables the TIM Capture Compare Channel xN.
+ * @param TIMx: where x can be 1 to select the TIM peripheral.
+ * @param TIM_Channel: specifies the TIM Channel
+ * This parmeter can be one of the following values:
+ * @arg TIM_Channel_1: TIM Channel 1
+ * @arg TIM_Channel_2: TIM Channel 2
+ * @arg TIM_Channel_3: TIM Channel 3
+ * @param TIM_CCxN: specifies the TIM Channel CCxNE bit new state.
+ * This parameter can be: TIM_CCxN_Enable or TIM_CCxN_Disable.
+ * @retval None
+ */
+void TIM_CCxNCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCxN)
+{
+ uint16_t tmp = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST2_PERIPH(TIMx));
+ assert_param(IS_TIM_COMPLEMENTARY_CHANNEL(TIM_Channel));
+ assert_param(IS_TIM_CCXN(TIM_CCxN));
+
+ tmp = CCER_CCNE_SET << TIM_Channel;
+
+ /* Reset the CCxNE Bit */
+ TIMx->CCER &= (uint16_t) ~tmp;
+
+ /* Set or reset the CCxNE Bit */
+ TIMx->CCER |= (uint16_t)(TIM_CCxN << TIM_Channel);
+}
+
+/**
+ * @brief Selects the TIM peripheral Commutation event.
+ * @param TIMx: where x can be 1 to select the TIMx peripheral
+ * @param NewState: new state of the Commutation event.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void TIM_SelectCOM(TIM_TypeDef* TIMx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST2_PERIPH(TIMx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Set the COM Bit */
+ TIMx->CR2 |= TIM_CR2_CCUS;
+ }
+ else
+ {
+ /* Reset the COM Bit */
+ TIMx->CR2 &= (uint16_t)~((uint16_t)TIM_CR2_CCUS);
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Group4 Input Capture management functions
+ * @brief Input Capture management functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Input Capture management functions #####
+ ===============================================================================
+
+ *** TIM Driver: how to use it in Input Capture Mode ***
+ ===============================================================================
+ [..] To use the Timer in Input Capture mode, the following steps are mandatory:
+ (#) Enable TIM clock using RCC_APBxPeriphClockCmd(RCC_APBxPeriph_TIMx, ENABLE)
+ function.
+ (#) Configure the TIM pins by configuring the corresponding GPIO pins.
+ (#) Configure the Time base unit as described in the first part of this
+ driver, if needed, else the Timer will run with the default configuration:
+ (++) Autoreload value = 0xFFFF.
+ (++) Prescaler value = 0x0000.
+ (++) Counter mode = Up counting.
+ (++) Clock Division = TIM_CKD_DIV1.
+ (#) Fill the TIM_ICInitStruct with the desired parameters including:
+ (++) TIM Channel: TIM_Channel.
+ (++) TIM Input Capture polarity: TIM_ICPolarity.
+ (++) TIM Input Capture selection: TIM_ICSelection.
+ (++) TIM Input Capture Prescaler: TIM_ICPrescaler.
+ (++) TIM Input CApture filter value: TIM_ICFilter.
+ (#) Call TIM_ICInit(TIMx, &TIM_ICInitStruct) to configure the desired
+ channel with the corresponding configuration and to measure only
+ frequency or duty cycle of the input signal,or, Call
+ TIM_PWMIConfig(TIMx, &TIM_ICInitStruct) to configure the desired
+ channels with the corresponding configuration and to measure the
+ frequency and the duty cycle of the input signal.
+ (#) Enable the NVIC or the DMA to read the measured frequency.
+ (#) Enable the corresponding interrupt (or DMA request) to read
+ the Captured value, using the function TIM_ITConfig(TIMx, TIM_IT_CCx)
+ (or TIM_DMA_Cmd(TIMx, TIM_DMA_CCx)).
+ (#) Call the TIM_Cmd(ENABLE) function to enable the TIM counter.
+ (#) Use TIM_GetCapturex(TIMx); to read the captured value.
+ [..]
+ (@) All other functions can be used separately to modify, if needed,
+ a specific feature of the Timer.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the TIM peripheral according to the specified
+ * parameters in the TIM_ICInitStruct.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_ICInitStruct: pointer to a TIM_ICInitTypeDef structure
+ * that contains the configuration information for the specified TIM
+ * peripheral.
+ * @retval None
+ */
+void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST4_PERIPH(TIMx));
+ assert_param(IS_TIM_CHANNEL(TIM_ICInitStruct->TIM_Channel));
+ assert_param(IS_TIM_IC_SELECTION(TIM_ICInitStruct->TIM_ICSelection));
+ assert_param(IS_TIM_IC_PRESCALER(TIM_ICInitStruct->TIM_ICPrescaler));
+ assert_param(IS_TIM_IC_FILTER(TIM_ICInitStruct->TIM_ICFilter));
+ assert_param(IS_TIM_IC_POLARITY(TIM_ICInitStruct->TIM_ICPolarity));
+
+ if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_1)
+ {
+ assert_param(IS_TIM_LIST4_PERIPH(TIMx));
+ /* TI1 Configuration */
+ TI1_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity,
+ TIM_ICInitStruct->TIM_ICSelection,
+ TIM_ICInitStruct->TIM_ICFilter);
+ /* Set the Input Capture Prescaler value */
+ TIM_SetIC1Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler);
+ }
+ else if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_2)
+ {
+ assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+ /* TI2 Configuration */
+ TI2_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity,
+ TIM_ICInitStruct->TIM_ICSelection,
+ TIM_ICInitStruct->TIM_ICFilter);
+ /* Set the Input Capture Prescaler value */
+ TIM_SetIC2Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler);
+ }
+ else if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_3)
+ {
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ /* TI3 Configuration */
+ TI3_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity,
+ TIM_ICInitStruct->TIM_ICSelection,
+ TIM_ICInitStruct->TIM_ICFilter);
+ /* Set the Input Capture Prescaler value */
+ TIM_SetIC3Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler);
+ }
+ else
+ {
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ /* TI4 Configuration */
+ TI4_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity,
+ TIM_ICInitStruct->TIM_ICSelection,
+ TIM_ICInitStruct->TIM_ICFilter);
+ /* Set the Input Capture Prescaler value */
+ TIM_SetIC4Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler);
+ }
+}
+
+/**
+ * @brief Fills each TIM_ICInitStruct member with its default value.
+ * @param TIM_ICInitStruct: pointer to a TIM_ICInitTypeDef structure which will
+ * be initialized.
+ * @retval None
+ */
+void TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitStruct)
+{
+ /* Set the default configuration */
+ TIM_ICInitStruct->TIM_Channel = TIM_Channel_1;
+ TIM_ICInitStruct->TIM_ICPolarity = TIM_ICPolarity_Rising;
+ TIM_ICInitStruct->TIM_ICSelection = TIM_ICSelection_DirectTI;
+ TIM_ICInitStruct->TIM_ICPrescaler = TIM_ICPSC_DIV1;
+ TIM_ICInitStruct->TIM_ICFilter = 0x00;
+}
+
+/**
+ * @brief Configures the TIM peripheral according to the specified
+ * parameters in the TIM_ICInitStruct to measure an external PWM signal.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_ICInitStruct: pointer to a TIM_ICInitTypeDef structure
+ * that contains the configuration information for the specified TIM
+ * peripheral.
+ * @retval None
+ */
+void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct)
+{
+ uint16_t icoppositepolarity = TIM_ICPolarity_Rising;
+ uint16_t icoppositeselection = TIM_ICSelection_DirectTI;
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+ /* Select the Opposite Input Polarity */
+ if (TIM_ICInitStruct->TIM_ICPolarity == TIM_ICPolarity_Rising)
+ {
+ icoppositepolarity = TIM_ICPolarity_Falling;
+ }
+ else
+ {
+ icoppositepolarity = TIM_ICPolarity_Rising;
+ }
+ /* Select the Opposite Input */
+ if (TIM_ICInitStruct->TIM_ICSelection == TIM_ICSelection_DirectTI)
+ {
+ icoppositeselection = TIM_ICSelection_IndirectTI;
+ }
+ else
+ {
+ icoppositeselection = TIM_ICSelection_DirectTI;
+ }
+ if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_1)
+ {
+ /* TI1 Configuration */
+ TI1_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, TIM_ICInitStruct->TIM_ICSelection,
+ TIM_ICInitStruct->TIM_ICFilter);
+ /* Set the Input Capture Prescaler value */
+ TIM_SetIC1Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler);
+ /* TI2 Configuration */
+ TI2_Config(TIMx, icoppositepolarity, icoppositeselection, TIM_ICInitStruct->TIM_ICFilter);
+ /* Set the Input Capture Prescaler value */
+ TIM_SetIC2Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler);
+ }
+ else
+ {
+ /* TI2 Configuration */
+ TI2_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, TIM_ICInitStruct->TIM_ICSelection,
+ TIM_ICInitStruct->TIM_ICFilter);
+ /* Set the Input Capture Prescaler value */
+ TIM_SetIC2Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler);
+ /* TI1 Configuration */
+ TI1_Config(TIMx, icoppositepolarity, icoppositeselection, TIM_ICInitStruct->TIM_ICFilter);
+ /* Set the Input Capture Prescaler value */
+ TIM_SetIC1Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler);
+ }
+}
+
+/**
+ * @brief Gets the TIMx Input Capture 1 value.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @retval Capture Compare 1 Register value.
+ */
+uint32_t TIM_GetCapture1(TIM_TypeDef* TIMx)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST4_PERIPH(TIMx));
+
+ /* Get the Capture 1 Register value */
+ return TIMx->CCR1;
+}
+
+/**
+ * @brief Gets the TIMx Input Capture 2 value.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @retval Capture Compare 2 Register value.
+ */
+uint32_t TIM_GetCapture2(TIM_TypeDef* TIMx)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+
+ /* Get the Capture 2 Register value */
+ return TIMx->CCR2;
+}
+
+/**
+ * @brief Gets the TIMx Input Capture 3 value.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @retval Capture Compare 3 Register value.
+ */
+uint32_t TIM_GetCapture3(TIM_TypeDef* TIMx)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+
+ /* Get the Capture 3 Register value */
+ return TIMx->CCR3;
+}
+
+/**
+ * @brief Gets the TIMx Input Capture 4 value.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @retval Capture Compare 4 Register value.
+ */
+uint32_t TIM_GetCapture4(TIM_TypeDef* TIMx)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+
+ /* Get the Capture 4 Register value */
+ return TIMx->CCR4;
+}
+
+/**
+ * @brief Sets the TIMx Input Capture 1 prescaler.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_ICPSC: specifies the Input Capture1 prescaler new value.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICPSC_DIV1: no prescaler
+ * @arg TIM_ICPSC_DIV2: capture is done once every 2 events
+ * @arg TIM_ICPSC_DIV4: capture is done once every 4 events
+ * @arg TIM_ICPSC_DIV8: capture is done once every 8 events
+ * @retval None
+ */
+void TIM_SetIC1Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST4_PERIPH(TIMx));
+ assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC));
+
+ /* Reset the IC1PSC Bits */
+ TIMx->CCMR1 &= (uint16_t)~((uint16_t)TIM_CCMR1_IC1PSC);
+ /* Set the IC1PSC value */
+ TIMx->CCMR1 |= TIM_ICPSC;
+}
+
+/**
+ * @brief Sets the TIMx Input Capture 2 prescaler.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_ICPSC: specifies the Input Capture2 prescaler new value.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICPSC_DIV1: no prescaler
+ * @arg TIM_ICPSC_DIV2: capture is done once every 2 events
+ * @arg TIM_ICPSC_DIV4: capture is done once every 4 events
+ * @arg TIM_ICPSC_DIV8: capture is done once every 8 events
+ * @retval None
+ */
+void TIM_SetIC2Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+ assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC));
+
+ /* Reset the IC2PSC Bits */
+ TIMx->CCMR1 &= (uint16_t)~((uint16_t)TIM_CCMR1_IC2PSC);
+ /* Set the IC2PSC value */
+ TIMx->CCMR1 |= (uint16_t)(TIM_ICPSC << 8);
+}
+
+/**
+ * @brief Sets the TIMx Input Capture 3 prescaler.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_ICPSC: specifies the Input Capture3 prescaler new value.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICPSC_DIV1: no prescaler
+ * @arg TIM_ICPSC_DIV2: capture is done once every 2 events
+ * @arg TIM_ICPSC_DIV4: capture is done once every 4 events
+ * @arg TIM_ICPSC_DIV8: capture is done once every 8 events
+ * @retval None
+ */
+void TIM_SetIC3Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC));
+
+ /* Reset the IC3PSC Bits */
+ TIMx->CCMR2 &= (uint16_t)~((uint16_t)TIM_CCMR2_IC3PSC);
+ /* Set the IC3PSC value */
+ TIMx->CCMR2 |= TIM_ICPSC;
+}
+
+/**
+ * @brief Sets the TIMx Input Capture 4 prescaler.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_ICPSC: specifies the Input Capture4 prescaler new value.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICPSC_DIV1: no prescaler
+ * @arg TIM_ICPSC_DIV2: capture is done once every 2 events
+ * @arg TIM_ICPSC_DIV4: capture is done once every 4 events
+ * @arg TIM_ICPSC_DIV8: capture is done once every 8 events
+ * @retval None
+ */
+void TIM_SetIC4Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC));
+
+ /* Reset the IC4PSC Bits */
+ TIMx->CCMR2 &= (uint16_t)~((uint16_t)TIM_CCMR2_IC4PSC);
+ /* Set the IC4PSC value */
+ TIMx->CCMR2 |= (uint16_t)(TIM_ICPSC << 8);
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Group5 Interrupts and flags management functions
+ * @brief Interrupts and flags management functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Interrupts and flags management functions #####
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the specified TIM interrupts.
+ * @param TIMx: where x can be 1, 2, 6 to select the TIMx peripheral.
+ * @param TIM_IT: specifies the TIM interrupts sources to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * @arg TIM_IT_Update: TIM update Interrupt source
+ * @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source
+ * @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source
+ * @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source
+ * @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source
+ * @arg TIM_IT_COM: TIM Commutation Interrupt source
+ * @arg TIM_IT_Trigger: TIM Trigger Interrupt source
+ * @arg TIM_IT_Break: TIM Break Interrupt source
+ *
+ * @note TIM6 can only generate an update interrupt.
+ * @note TIM_IT_Break is used only with TIM1.
+ * @note TIM_IT_COM is used only with TIM1.
+ *
+ * @param NewState: new state of the TIM interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ assert_param(IS_TIM_IT(TIM_IT));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the Interrupt sources */
+ TIMx->DIER |= TIM_IT;
+ }
+ else
+ {
+ /* Disable the Interrupt sources */
+ TIMx->DIER &= (uint16_t)~TIM_IT;
+ }
+}
+
+/**
+ * @brief Configures the TIMx event to be generate by software.
+ * @param TIMx: where x can be 1, 2, 6 to select the
+ * TIM peripheral.
+ * @param TIM_EventSource: specifies the event source.
+ * This parameter can be one or more of the following values:
+ * @arg TIM_EventSource_Update: Timer update Event source
+ * @arg TIM_EventSource_CC1: Timer Capture Compare 1 Event source
+ * @arg TIM_EventSource_CC2: Timer Capture Compare 2 Event source
+ * @arg TIM_EventSource_CC3: Timer Capture Compare 3 Event source
+ * @arg TIM_EventSource_CC4: Timer Capture Compare 4 Event source
+ * @arg TIM_EventSource_COM: Timer COM event source
+ * @arg TIM_EventSource_Trigger: Timer Trigger Event source
+ * @arg TIM_EventSource_Break: Timer Break event source
+ *
+ * @note TIM6 can only generate an update event.
+ * @note TIM_EventSource_COM and TIM_EventSource_Break are used only with TIM1.
+ *
+ * @retval None
+ */
+void TIM_GenerateEvent(TIM_TypeDef* TIMx, uint16_t TIM_EventSource)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ assert_param(IS_TIM_EVENT_SOURCE(TIM_EventSource));
+ /* Set the event sources */
+ TIMx->EGR = TIM_EventSource;
+}
+
+/**
+ * @brief Checks whether the specified TIM flag is set or not.
+ * @param TIMx: where x can be 1, 2, 6 to select the TIM peripheral.
+ * @param TIM_FLAG: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg TIM_FLAG_Update: TIM update Flag
+ * @arg TIM_FLAG_CC1: TIM Capture Compare 1 Flag
+ * @arg TIM_FLAG_CC2: TIM Capture Compare 2 Flag
+ * @arg TIM_FLAG_CC3: TIM Capture Compare 3 Flag
+ * @arg TIM_FLAG_CC4: TIM Capture Compare 4 Flag
+ * @arg TIM_FLAG_COM: TIM Commutation Flag
+ * @arg TIM_FLAG_Trigger: TIM Trigger Flag
+ * @arg TIM_FLAG_Break: TIM Break Flag
+ * @arg TIM_FLAG_CC1OF: TIM Capture Compare 1 overcapture Flag
+ * @arg TIM_FLAG_CC2OF: TIM Capture Compare 2 overcapture Flag
+ * @arg TIM_FLAG_CC3OF: TIM Capture Compare 3 overcapture Flag
+ * @arg TIM_FLAG_CC4OF: TIM Capture Compare 4 overcapture Flag
+ *
+ * @note TIM6 can have only one update flag.
+ * @note TIM_FLAG_Break is used only with TIM1.
+ * @note TIM_FLAG_COM is used only with TIM1.
+ *
+ * @retval The new state of TIM_FLAG (SET or RESET).
+ */
+FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG)
+{
+ ITStatus bitstatus = RESET;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ assert_param(IS_TIM_GET_FLAG(TIM_FLAG));
+
+ if ((TIMx->SR & TIM_FLAG) != (uint16_t)RESET)
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the TIMx's pending flags.
+ * @param TIMx: where x can be 1, 2, 6 to select the TIM peripheral.
+ * @param TIM_FLAG: specifies the flag bit to clear.
+ * This parameter can be any combination of the following values:
+ * @arg TIM_FLAG_Update: TIM update Flag
+ * @arg TIM_FLAG_CC1: TIM Capture Compare 1 Flag
+ * @arg TIM_FLAG_CC2: TIM Capture Compare 2 Flag
+ * @arg TIM_FLAG_CC3: TIM Capture Compare 3 Flag
+ * @arg TIM_FLAG_CC4: TIM Capture Compare 4 Flag
+ * @arg TIM_FLAG_COM: TIM Commutation Flag
+ * @arg TIM_FLAG_Trigger: TIM Trigger Flag
+ * @arg TIM_FLAG_Break: TIM Break Flag
+ * @arg TIM_FLAG_CC1OF: TIM Capture Compare 1 overcapture Flag
+ * @arg TIM_FLAG_CC2OF: TIM Capture Compare 2 overcapture Flag
+ * @arg TIM_FLAG_CC3OF: TIM Capture Compare 3 overcapture Flag
+ * @arg TIM_FLAG_CC4OF: TIM Capture Compare 4 overcapture Flag
+ *
+ * @note TIM6 can have only one update flag.
+ * @note TIM_FLAG_Break is used only with TIM1.
+ * @note TIM_FLAG_COM is used only with TIM1.
+ *
+ * @retval None
+ */
+void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ assert_param(IS_TIM_CLEAR_FLAG(TIM_FLAG));
+
+ /* Clear the flags */
+ TIMx->SR = (uint16_t)~TIM_FLAG;
+}
+
+/**
+ * @brief Checks whether the TIM interrupt has occurred or not.
+ * @param TIMx: where x can be 1, 2, 6 to select the TIM peripheral.
+ * @param TIM_IT: specifies the TIM interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg TIM_IT_Update: TIM update Interrupt source
+ * @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source
+ * @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source
+ * @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source
+ * @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source
+ * @arg TIM_IT_COM: TIM Commutation Interrupt source
+ * @arg TIM_IT_Trigger: TIM Trigger Interrupt source
+ * @arg TIM_IT_Break: TIM Break Interrupt source
+ *
+ * @note TIM6 can generate only an update interrupt.
+ * @note TIM_IT_Break is used only with TIM1.
+ * @note TIM_IT_COM is used only with TIM1.
+ *
+ * @retval The new state of the TIM_IT(SET or RESET).
+ */
+ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT)
+{
+ ITStatus bitstatus = RESET;
+ uint16_t itstatus = 0x0, itenable = 0x0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ assert_param(IS_TIM_GET_IT(TIM_IT));
+
+ itstatus = TIMx->SR & TIM_IT;
+
+ itenable = TIMx->DIER & TIM_IT;
+ if ((itstatus != (uint16_t)RESET) && (itenable != (uint16_t)RESET))
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the TIMx's interrupt pending bits.
+ * @param TIMx: where x can be 1, 2, 6 to select the TIM peripheral.
+ * @param TIM_IT: specifies the pending bit to clear.
+ * This parameter can be any combination of the following values:
+ * @arg TIM_IT_Update: TIM1 update Interrupt source
+ * @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source
+ * @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source
+ * @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source
+ * @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source
+ * @arg TIM_IT_COM: TIM Commutation Interrupt source
+ * @arg TIM_IT_Trigger: TIM Trigger Interrupt source
+ * @arg TIM_IT_Break: TIM Break Interrupt source
+ *
+ * @note TIM6 can generate only an update interrupt.
+ * @note TIM_IT_Break is used only with TIM1.
+ * @note TIM_IT_COM is used only with TIM1.
+ *
+ * @retval None
+ */
+void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ assert_param(IS_TIM_IT(TIM_IT));
+
+ /* Clear the IT pending Bit */
+ TIMx->SR = (uint16_t)~TIM_IT;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Group6 Clocks management functions
+ * @brief Clocks management functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Clocks management functions #####
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Configures the TIMx internal Clock
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @retval None
+ */
+void TIM_InternalClockConfig(TIM_TypeDef* TIMx)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+ /* Disable slave mode to clock the prescaler directly with the internal clock */
+ TIMx->SMCR &= (uint16_t)(~((uint16_t)TIM_SMCR_SMS));
+}
+
+/**
+ * @brief Configures the TIMx Internal Trigger as External Clock
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_ITRSource: Trigger source.
+ * This parameter can be one of the following values:
+ * @arg TIM_TS_ITR0: Internal Trigger 0
+ * @arg TIM_TS_ITR1: Internal Trigger 1
+ * @arg TIM_TS_ITR2: Internal Trigger 2
+ * @arg TIM_TS_ITR3: Internal Trigger 3
+ * @retval None
+ */
+void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+ assert_param(IS_TIM_INTERNAL_TRIGGER_SELECTION(TIM_InputTriggerSource));
+ /* Select the Internal Trigger */
+ TIM_SelectInputTrigger(TIMx, TIM_InputTriggerSource);
+ /* Select the External clock mode1 */
+ TIMx->SMCR |= TIM_SlaveMode_External1;
+}
+
+/**
+ * @brief Configures the TIMx Trigger as External Clock
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_TIxExternalCLKSource: Trigger source.
+ * This parameter can be one of the following values:
+ * @arg TIM_TIxExternalCLK1Source_TI1ED: TI1 Edge Detector
+ * @arg TIM_TIxExternalCLK1Source_TI1: Filtered Timer Input 1
+ * @arg TIM_TIxExternalCLK1Source_TI2: Filtered Timer Input 2
+ * @param TIM_ICPolarity: specifies the TIx Polarity.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICPolarity_Rising
+ * @arg TIM_ICPolarity_Falling
+ * @param ICFilter: specifies the filter value.
+ * This parameter must be a value between 0x0 and 0xF.
+ * @retval None
+ */
+void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource,
+ uint16_t TIM_ICPolarity, uint16_t ICFilter)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+ assert_param(IS_TIM_IC_POLARITY(TIM_ICPolarity));
+ assert_param(IS_TIM_IC_FILTER(ICFilter));
+
+ /* Configure the Timer Input Clock Source */
+ if (TIM_TIxExternalCLKSource == TIM_TIxExternalCLK1Source_TI2)
+ {
+ TI2_Config(TIMx, TIM_ICPolarity, TIM_ICSelection_DirectTI, ICFilter);
+ }
+ else
+ {
+ TI1_Config(TIMx, TIM_ICPolarity, TIM_ICSelection_DirectTI, ICFilter);
+ }
+ /* Select the Trigger source */
+ TIM_SelectInputTrigger(TIMx, TIM_TIxExternalCLKSource);
+ /* Select the External clock mode1 */
+ TIMx->SMCR |= TIM_SlaveMode_External1;
+}
+
+/**
+ * @brief Configures the External clock Mode1
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler.
+ * This parameter can be one of the following values:
+ * @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF.
+ * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2.
+ * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4.
+ * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8.
+ * @param TIM_ExtTRGPolarity: The external Trigger Polarity.
+ * This parameter can be one of the following values:
+ * @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active.
+ * @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active.
+ * @param ExtTRGFilter: External Trigger Filter.
+ * This parameter must be a value between 0x00 and 0x0F
+ * @retval None
+ */
+void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,
+ uint16_t ExtTRGFilter)
+{
+ uint16_t tmpsmcr = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_EXT_PRESCALER(TIM_ExtTRGPrescaler));
+ assert_param(IS_TIM_EXT_POLARITY(TIM_ExtTRGPolarity));
+ assert_param(IS_TIM_EXT_FILTER(ExtTRGFilter));
+
+ /* Configure the ETR Clock source */
+ TIM_ETRConfig(TIMx, TIM_ExtTRGPrescaler, TIM_ExtTRGPolarity, ExtTRGFilter);
+
+ /* Get the TIMx SMCR register value */
+ tmpsmcr = TIMx->SMCR;
+ /* Reset the SMS Bits */
+ tmpsmcr &= (uint16_t)(~((uint16_t)TIM_SMCR_SMS));
+ /* Select the External clock mode1 */
+ tmpsmcr |= TIM_SlaveMode_External1;
+ /* Select the Trigger selection : ETRF */
+ tmpsmcr &= (uint16_t)(~((uint16_t)TIM_SMCR_TS));
+ tmpsmcr |= TIM_TS_ETRF;
+ /* Write to TIMx SMCR */
+ TIMx->SMCR = tmpsmcr;
+}
+
+/**
+ * @brief Configures the External clock Mode2
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler.
+ * This parameter can be one of the following values:
+ * @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF.
+ * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2.
+ * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4.
+ * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8.
+ * @param TIM_ExtTRGPolarity: The external Trigger Polarity.
+ * This parameter can be one of the following values:
+ * @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active.
+ * @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active.
+ * @param ExtTRGFilter: External Trigger Filter.
+ * This parameter must be a value between 0x00 and 0x0F
+ * @retval None
+ */
+void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler,
+ uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_EXT_PRESCALER(TIM_ExtTRGPrescaler));
+ assert_param(IS_TIM_EXT_POLARITY(TIM_ExtTRGPolarity));
+ assert_param(IS_TIM_EXT_FILTER(ExtTRGFilter));
+
+ /* Configure the ETR Clock source */
+ TIM_ETRConfig(TIMx, TIM_ExtTRGPrescaler, TIM_ExtTRGPolarity, ExtTRGFilter);
+ /* Enable the External clock mode2 */
+ TIMx->SMCR |= TIM_SMCR_ECE;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Group7 Synchronization management functions
+ * @brief Synchronization management functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Synchronization management functions #####
+ ===============================================================================
+ *** TIM Driver: how to use it in synchronization Mode ***
+ ===============================================================================
+ [..] Case of two/several Timers
+ (#) Configure the Master Timers using the following functions:
+ (++) void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx,
+ uint16_t TIM_TRGOSource).
+ (++) void TIM_SelectMasterSlaveMode(TIM_TypeDef* TIMx,
+ uint16_t TIM_MasterSlaveMode);
+ (#) Configure the Slave Timers using the following functions:
+ (++) void TIM_SelectInputTrigger(TIM_TypeDef* TIMx,
+ uint16_t TIM_InputTriggerSource);
+ (++) void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode);
+ [..] Case of Timers and external trigger(ETR pin)
+ (#) Configure the Etrenal trigger using this function:
+ (++) void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler,
+ uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);
+ (#) Configure the Slave Timers using the following functions:
+ (++) void TIM_SelectInputTrigger(TIM_TypeDef* TIMx,
+ uint16_t TIM_InputTriggerSource);
+ (++) void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode);
+
+@endverbatim
+ * @{
+ */
+/**
+ * @brief Selects the Input Trigger source
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_InputTriggerSource: The Input Trigger source.
+ * This parameter can be one of the following values:
+ * @arg TIM_TS_ITR0: Internal Trigger 0
+ * @arg TIM_TS_ITR1: Internal Trigger 1
+ * @arg TIM_TS_ITR2: Internal Trigger 2
+ * @arg TIM_TS_ITR3: Internal Trigger 3
+ * @arg TIM_TS_TI1F_ED: TI1 Edge Detector
+ * @arg TIM_TS_TI1FP1: Filtered Timer Input 1
+ * @arg TIM_TS_TI2FP2: Filtered Timer Input 2
+ * @arg TIM_TS_ETRF: External Trigger input
+ * @retval None
+ */
+void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource)
+{
+ uint16_t tmpsmcr = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+ assert_param(IS_TIM_TRIGGER_SELECTION(TIM_InputTriggerSource));
+
+ /* Get the TIMx SMCR register value */
+ tmpsmcr = TIMx->SMCR;
+ /* Reset the TS Bits */
+ tmpsmcr &= (uint16_t)(~((uint16_t)TIM_SMCR_TS));
+ /* Set the Input Trigger source */
+ tmpsmcr |= TIM_InputTriggerSource;
+ /* Write to TIMx SMCR */
+ TIMx->SMCR = tmpsmcr;
+}
+
+/**
+ * @brief Selects the TIMx Trigger Output Mode.
+ * @param TIMx: where x can be 1, 2, 6 to select the TIM peripheral.
+ * @param TIM_TRGOSource: specifies the Trigger Output source.
+ * This parameter can be one of the following values:
+ *
+ * - For all TIMx
+ * @arg TIM_TRGOSource_Reset: The UG bit in the TIM_EGR register is used as the trigger output (TRGO).
+ * @arg TIM_TRGOSource_Enable: The Counter Enable CEN is used as the trigger output (TRGO).
+ * @arg TIM_TRGOSource_Update: The update event is selected as the trigger output (TRGO).
+ *
+ * - For all TIMx except TIM6
+ * @arg TIM_TRGOSource_OC1: The trigger output sends a positive pulse when the CC1IF flag
+ * is to be set, as soon as a capture or compare match occurs (TRGO).
+ * @arg TIM_TRGOSource_OC1Ref: OC1REF signal is used as the trigger output (TRGO).
+ * @arg TIM_TRGOSource_OC2Ref: OC2REF signal is used as the trigger output (TRGO).
+ * @arg TIM_TRGOSource_OC3Ref: OC3REF signal is used as the trigger output (TRGO).
+ * @arg TIM_TRGOSource_OC4Ref: OC4REF signal is used as the trigger output (TRGO).
+ *
+ * @retval None
+ */
+void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST9_PERIPH(TIMx));
+ assert_param(IS_TIM_TRGO_SOURCE(TIM_TRGOSource));
+
+ /* Reset the MMS Bits */
+ TIMx->CR2 &= (uint16_t)~((uint16_t)TIM_CR2_MMS);
+ /* Select the TRGO source */
+ TIMx->CR2 |= TIM_TRGOSource;
+}
+
+/**
+ * @brief Selects the TIMx Slave Mode.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_SlaveMode: specifies the Timer Slave Mode.
+ * This parameter can be one of the following values:
+ * @arg TIM_SlaveMode_Reset: Rising edge of the selected trigger signal (TRGI) re-initializes
+ * the counter and triggers an update of the registers.
+ * @arg TIM_SlaveMode_Gated: The counter clock is enabled when the trigger signal (TRGI) is high.
+ * @arg TIM_SlaveMode_Trigger: The counter starts at a rising edge of the trigger TRGI.
+ * @arg TIM_SlaveMode_External1: Rising edges of the selected trigger (TRGI) clock the counter.
+ * @retval None
+ */
+void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+ assert_param(IS_TIM_SLAVE_MODE(TIM_SlaveMode));
+
+ /* Reset the SMS Bits */
+ TIMx->SMCR &= (uint16_t)~((uint16_t)TIM_SMCR_SMS);
+ /* Select the Slave Mode */
+ TIMx->SMCR |= TIM_SlaveMode;
+}
+
+/**
+ * @brief Sets or Resets the TIMx Master/Slave Mode.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_MasterSlaveMode: specifies the Timer Master Slave Mode.
+ * This parameter can be one of the following values:
+ * @arg TIM_MasterSlaveMode_Enable: synchronization between the current timer
+ * and its slaves (through TRGO).
+ * @arg TIM_MasterSlaveMode_Disable: No action
+ * @retval None
+ */
+void TIM_SelectMasterSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_MasterSlaveMode)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+ assert_param(IS_TIM_MSM_STATE(TIM_MasterSlaveMode));
+
+ /* Reset the MSM Bit */
+ TIMx->SMCR &= (uint16_t)~((uint16_t)TIM_SMCR_MSM);
+
+ /* Set or Reset the MSM Bit */
+ TIMx->SMCR |= TIM_MasterSlaveMode;
+}
+
+/**
+ * @brief Configures the TIMx External Trigger (ETR).
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler.
+ * This parameter can be one of the following values:
+ * @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF.
+ * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2.
+ * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4.
+ * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8.
+ * @param TIM_ExtTRGPolarity: The external Trigger Polarity.
+ * This parameter can be one of the following values:
+ * @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active.
+ * @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active.
+ * @param ExtTRGFilter: External Trigger Filter.
+ * This parameter must be a value between 0x00 and 0x0F
+ * @retval None
+ */
+void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,
+ uint16_t ExtTRGFilter)
+{
+ uint16_t tmpsmcr = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_EXT_PRESCALER(TIM_ExtTRGPrescaler));
+ assert_param(IS_TIM_EXT_POLARITY(TIM_ExtTRGPolarity));
+ assert_param(IS_TIM_EXT_FILTER(ExtTRGFilter));
+
+ tmpsmcr = TIMx->SMCR;
+ /* Reset the ETR Bits */
+ tmpsmcr &= SMCR_ETR_MASK;
+ /* Set the Prescaler, the Filter value and the Polarity */
+ tmpsmcr |= (uint16_t)(TIM_ExtTRGPrescaler | (uint16_t)(TIM_ExtTRGPolarity | (uint16_t)(ExtTRGFilter << (uint16_t)8)));
+ /* Write to TIMx SMCR */
+ TIMx->SMCR = tmpsmcr;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Group8 Specific interface management functions
+ * @brief Specific interface management functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Specific interface management functions #####
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Configures the TIMx Encoder Interface.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_EncoderMode: specifies the TIMx Encoder Mode.
+ * This parameter can be one of the following values:
+ * @arg TIM_EncoderMode_TI1: Counter counts on TI1FP1 edge depending on TI2FP2 level.
+ * @arg TIM_EncoderMode_TI2: Counter counts on TI2FP2 edge depending on TI1FP1 level.
+ * @arg TIM_EncoderMode_TI12: Counter counts on both TI1FP1 and TI2FP2 edges depending
+ * on the level of the other input.
+ * @param TIM_IC1Polarity: specifies the IC1 Polarity
+ * This parmeter can be one of the following values:
+ * @arg TIM_ICPolarity_Falling: IC Falling edge.
+ * @arg TIM_ICPolarity_Rising: IC Rising edge.
+ * @param TIM_IC2Polarity: specifies the IC2 Polarity
+ * This parmeter can be one of the following values:
+ * @arg TIM_ICPolarity_Falling: IC Falling edge.
+ * @arg TIM_ICPolarity_Rising: IC Rising edge.
+ * @retval None
+ */
+void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode,
+ uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity)
+{
+ uint16_t tmpsmcr = 0;
+ uint16_t tmpccmr1 = 0;
+ uint16_t tmpccer = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_ENCODER_MODE(TIM_EncoderMode));
+ assert_param(IS_TIM_IC_POLARITY(TIM_IC1Polarity));
+ assert_param(IS_TIM_IC_POLARITY(TIM_IC2Polarity));
+
+ /* Get the TIMx SMCR register value */
+ tmpsmcr = TIMx->SMCR;
+ /* Get the TIMx CCMR1 register value */
+ tmpccmr1 = TIMx->CCMR1;
+ /* Get the TIMx CCER register value */
+ tmpccer = TIMx->CCER;
+ /* Set the encoder Mode */
+ tmpsmcr &= (uint16_t)(~((uint16_t)TIM_SMCR_SMS));
+ tmpsmcr |= TIM_EncoderMode;
+ /* Select the Capture Compare 1 and the Capture Compare 2 as input */
+ tmpccmr1 &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCMR1_CC1S)) & (uint16_t)(~((uint16_t)TIM_CCMR1_CC2S)));
+ tmpccmr1 |= TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0;
+ /* Set the TI1 and the TI2 Polarities */
+ tmpccer &= (uint16_t)~((uint16_t)(TIM_CCER_CC1P | TIM_CCER_CC1NP)) & (uint16_t)~((uint16_t)(TIM_CCER_CC2P | TIM_CCER_CC2NP));
+ tmpccer |= (uint16_t)(TIM_IC1Polarity | (uint16_t)(TIM_IC2Polarity << (uint16_t)4));
+ /* Write to TIMx SMCR */
+ TIMx->SMCR = tmpsmcr;
+ /* Write to TIMx CCMR1 */
+ TIMx->CCMR1 = tmpccmr1;
+ /* Write to TIMx CCER */
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Enables or disables the TIMx's Hall sensor interface.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param NewState: new state of the TIMx Hall sensor interface.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void TIM_SelectHallSensor(TIM_TypeDef* TIMx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Set the TI1S Bit */
+ TIMx->CR2 |= TIM_CR2_TI1S;
+ }
+ else
+ {
+ /* Reset the TI1S Bit */
+ TIMx->CR2 &= (uint16_t)~((uint16_t)TIM_CR2_TI1S);
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Group9 Specific remapping management function
+ * @brief Specific remapping management function
+ *
+@verbatim
+ ===============================================================================
+ ##### Specific remapping management function #####
+ ===============================================================================
+
+**
+ * @}
+ */
+
+/**
+ * @brief Configure the TI1 as Input.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_ICPolarity: The Input Polarity.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICPolarity_Rising
+ * @arg TIM_ICPolarity_Falling
+ * @param TIM_ICSelection: specifies the input to be used.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICSelection_DirectTI: TIM Input 1 is selected to be connected to IC1.
+ * @arg TIM_ICSelection_IndirectTI: TIM Input 1 is selected to be connected to IC2.
+ * @arg TIM_ICSelection_TRC: TIM Input 1 is selected to be connected to TRC.
+ * @param TIM_ICFilter: Specifies the Input Capture Filter.
+ * This parameter must be a value between 0x00 and 0x0F.
+ * @retval None
+ */
+static void TI1_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection,
+ uint16_t TIM_ICFilter)
+{
+ uint16_t tmpccmr1 = 0, tmpccer = 0;
+ /* Disable the Channel 1: Reset the CC1E Bit */
+ TIMx->CCER &= (uint16_t)~((uint16_t)TIM_CCER_CC1E);
+ tmpccmr1 = TIMx->CCMR1;
+ tmpccer = TIMx->CCER;
+ /* Select the Input and set the filter */
+ tmpccmr1 &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCMR1_CC1S)) & ((uint16_t)~((uint16_t)TIM_CCMR1_IC1F)));
+ tmpccmr1 |= (uint16_t)(TIM_ICSelection | (uint16_t)(TIM_ICFilter << (uint16_t)4));
+
+ /* Select the Polarity and set the CC1E Bit */
+ tmpccer &= (uint16_t)~((uint16_t)(TIM_CCER_CC1P | TIM_CCER_CC1NP));
+ tmpccer |= (uint16_t)(TIM_ICPolarity | (uint16_t)TIM_CCER_CC1E);
+ /* Write to TIMx CCMR1 and CCER registers */
+ TIMx->CCMR1 = tmpccmr1;
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Configure the TI2 as Input.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_ICPolarity: The Input Polarity.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICPolarity_Rising
+ * @arg TIM_ICPolarity_Falling
+ * @param TIM_ICSelection: specifies the input to be used.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICSelection_DirectTI: TIM Input 2 is selected to be connected to IC2.
+ * @arg TIM_ICSelection_IndirectTI: TIM Input 2 is selected to be connected to IC1.
+ * @arg TIM_ICSelection_TRC: TIM Input 2 is selected to be connected to TRC.
+ * @param TIM_ICFilter: Specifies the Input Capture Filter.
+ * This parameter must be a value between 0x00 and 0x0F.
+ * @retval None
+ */
+static void TI2_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection,
+ uint16_t TIM_ICFilter)
+{
+ uint16_t tmpccmr1 = 0, tmpccer = 0, tmp = 0;
+ /* Disable the Channel 2: Reset the CC2E Bit */
+ TIMx->CCER &= (uint16_t)~((uint16_t)TIM_CCER_CC2E);
+ tmpccmr1 = TIMx->CCMR1;
+ tmpccer = TIMx->CCER;
+ tmp = (uint16_t)(TIM_ICPolarity << 4);
+ /* Select the Input and set the filter */
+ tmpccmr1 &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCMR1_CC2S)) & ((uint16_t)~((uint16_t)TIM_CCMR1_IC2F)));
+ tmpccmr1 |= (uint16_t)(TIM_ICFilter << 12);
+ tmpccmr1 |= (uint16_t)(TIM_ICSelection << 8);
+ /* Select the Polarity and set the CC2E Bit */
+ tmpccer &= (uint16_t)~((uint16_t)(TIM_CCER_CC2P | TIM_CCER_CC2NP));
+ tmpccer |= (uint16_t)(tmp | (uint16_t)TIM_CCER_CC2E);
+ /* Write to TIMx CCMR1 and CCER registers */
+ TIMx->CCMR1 = tmpccmr1 ;
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Configure the TI3 as Input.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_ICPolarity: The Input Polarity.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICPolarity_Rising
+ * @arg TIM_ICPolarity_Falling
+ * @param TIM_ICSelection: specifies the input to be used.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICSelection_DirectTI: TIM Input 3 is selected to be connected to IC3.
+ * @arg TIM_ICSelection_IndirectTI: TIM Input 3 is selected to be connected to IC4.
+ * @arg TIM_ICSelection_TRC: TIM Input 3 is selected to be connected to TRC.
+ * @param TIM_ICFilter: Specifies the Input Capture Filter.
+ * This parameter must be a value between 0x00 and 0x0F.
+ * @retval None
+ */
+static void TI3_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection,
+ uint16_t TIM_ICFilter)
+{
+ uint16_t tmpccmr2 = 0, tmpccer = 0, tmp = 0;
+ /* Disable the Channel 3: Reset the CC3E Bit */
+ TIMx->CCER &= (uint16_t)~((uint16_t)TIM_CCER_CC3E);
+ tmpccmr2 = TIMx->CCMR2;
+ tmpccer = TIMx->CCER;
+ tmp = (uint16_t)(TIM_ICPolarity << 8);
+ /* Select the Input and set the filter */
+ tmpccmr2 &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCMR2_CC3S)) & ((uint16_t)~((uint16_t)TIM_CCMR2_IC3F)));
+ tmpccmr2 |= (uint16_t)(TIM_ICSelection | (uint16_t)(TIM_ICFilter << (uint16_t)4));
+ /* Select the Polarity and set the CC3E Bit */
+ tmpccer &= (uint16_t)~((uint16_t)(TIM_CCER_CC3P | TIM_CCER_CC3NP));
+ tmpccer |= (uint16_t)(tmp | (uint16_t)TIM_CCER_CC3E);
+ /* Write to TIMx CCMR2 and CCER registers */
+ TIMx->CCMR2 = tmpccmr2;
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Configure the TI4 as Input.
+ * @param TIMx: where x can be 1, 2 to select the TIM peripheral.
+ * @param TIM_ICPolarity: The Input Polarity.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICPolarity_Rising
+ * @arg TIM_ICPolarity_Falling
+ * @param TIM_ICSelection: specifies the input to be used.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICSelection_DirectTI: TIM Input 4 is selected to be connected to IC4.
+ * @arg TIM_ICSelection_IndirectTI: TIM Input 4 is selected to be connected to IC3.
+ * @arg TIM_ICSelection_TRC: TIM Input 4 is selected to be connected to TRC.
+ * @param TIM_ICFilter: Specifies the Input Capture Filter.
+ * This parameter must be a value between 0x00 and 0x0F.
+ * @retval None
+ */
+static void TI4_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection,
+ uint16_t TIM_ICFilter)
+{
+ uint16_t tmpccmr2 = 0, tmpccer = 0, tmp = 0;
+
+ /* Disable the Channel 4: Reset the CC4E Bit */
+ TIMx->CCER &= (uint16_t)~((uint16_t)TIM_CCER_CC4E);
+ tmpccmr2 = TIMx->CCMR2;
+ tmpccer = TIMx->CCER;
+ tmp = (uint16_t)(TIM_ICPolarity << 12);
+ /* Select the Input and set the filter */
+ tmpccmr2 &= (uint16_t)((uint16_t)(~(uint16_t)TIM_CCMR2_CC4S) & ((uint16_t)~((uint16_t)TIM_CCMR2_IC4F)));
+ tmpccmr2 |= (uint16_t)(TIM_ICSelection << 8);
+ tmpccmr2 |= (uint16_t)(TIM_ICFilter << 12);
+ /* Select the Polarity and set the CC4E Bit */
+ tmpccer &= (uint16_t)~((uint16_t)(TIM_CCER_CC4P | TIM_CCER_CC4NP));
+ tmpccer |= (uint16_t)(tmp | (uint16_t)TIM_CCER_CC4E);
+ /* Write to TIMx CCMR2 and CCER registers */
+ TIMx->CCMR2 = tmpccmr2;
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_usart.c b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_usart.c
new file mode 100644
index 0000000..c60e3a3
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_usart.c
@@ -0,0 +1,1836 @@
+/**
+ ******************************************************************************
+ * @file hk32f030m_usart.c
+ * @version V1.0.1
+ * author Rakan.Z/wing.Wang
+ * @date 2019-12-17
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "hk32f030m_usart.h"
+#include "hk32f030m_rcc.h"
+
+
+/** @defgroup USART
+ * @brief USART driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+
+/*!< USART CR1 register clear Mask ((~(uint32_t)0xFFFFE6F3)) */
+#define CR1_CLEAR_MASK ((uint32_t)(USART_CR1_M | USART_CR1_PCE | \
+ USART_CR1_PS | USART_CR1_TE | \
+ USART_CR1_RE))
+
+/*!< USART CR2 register clock bits clear Mask ((~(uint32_t)0xFFFFF0FF)) */
+#define CR2_CLOCK_CLEAR_MASK ((uint32_t)(USART_CR2_CLKEN | USART_CR2_CPOL | \
+ USART_CR2_CPHA | USART_CR2_LBCL))
+
+/*!< USART CR3 register clear Mask ((~(uint32_t)0xFFFFFCFF)) */
+#define CR3_CLEAR_MASK ((uint32_t)(USART_CR3_RTSE | USART_CR3_CTSE))
+
+/*!< USART Interrupts mask */
+#define IT_MASK ((uint32_t)0x000000FF)
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup USART_Private_Functions
+ * @{
+ */
+
+/** @defgroup USART_Group1 Initialization and Configuration 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),
+ 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 | |
+ +-------------------------------------------------------------+
+
+ (++) Hardware flow control.
+ (++) Receiver/transmitter modes.
+ [..] The USART_Init() function follows the USART asynchronous configuration
+ procedure(details for the procedure are available in reference manual.
+ (+) For the synchronous mode in addition to the asynchronous mode parameters
+ these parameters should be also configured:
+ (++) USART Clock Enabled.
+ (++) USART polarity.
+ (++) USART phase.
+ (++) USART LastBit.
+ [..] These parameters can be configured using the USART_ClockInit() function.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Deinitializes the USARTx peripheral registers to their default reset values.
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @retval None
+ */
+void USART_DeInit(USART_TypeDef* USARTx)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+
+ if (USARTx == USART1)
+ {
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, ENABLE);
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, DISABLE);
+ }
+}
+
+/**
+ * @brief Initializes the USARTx peripheral according to the specified
+ * parameters in the USART_InitStruct .
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @param USART_InitStruct: pointer to a USART_InitTypeDef structure that contains
+ * the configuration information for the specified USART peripheral.
+ * @retval None
+ */
+void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct)
+{
+ uint32_t divider = 0, apbclock = 0, tmpreg = 0;
+ RCC_ClocksTypeDef RCC_ClocksStatus;
+
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_BAUDRATE(USART_InitStruct->USART_BaudRate));
+ assert_param(IS_USART_WORD_LENGTH(USART_InitStruct->USART_WordLength));
+ assert_param(IS_USART_STOPBITS(USART_InitStruct->USART_StopBits));
+ assert_param(IS_USART_PARITY(USART_InitStruct->USART_Parity));
+ assert_param(IS_USART_MODE(USART_InitStruct->USART_Mode));
+ assert_param(IS_USART_HARDWARE_FLOW_CONTROL(USART_InitStruct->USART_HardwareFlowControl));
+
+ /* Disable USART */
+ USARTx->CR1 &= (uint32_t)~((uint32_t)USART_CR1_UE);
+
+ /*---------------------------- USART CR2 Configuration -----------------------*/
+ tmpreg = USARTx->CR2;
+ /* Clear STOP[13:12] bits */
+ tmpreg &= (uint32_t)~((uint32_t)USART_CR2_STOP);
+
+ /* Configure the USART Stop Bits, Clock, CPOL, CPHA and LastBit ------------*/
+ /* Set STOP[13:12] bits according to USART_StopBits value */
+ tmpreg |= (uint32_t)USART_InitStruct->USART_StopBits;
+
+ /* Write to USART CR2 */
+ USARTx->CR2 = tmpreg;
+
+ /*---------------------------- USART CR1 Configuration -----------------------*/
+ tmpreg = USARTx->CR1;
+ /* Clear M, PCE, PS, TE and RE bits */
+ tmpreg &= (uint32_t)~((uint32_t)CR1_CLEAR_MASK);
+
+ /* Configure the USART Word Length, Parity and mode ----------------------- */
+ /* Set the M bits according to USART_WordLength value */
+ /* Set PCE and PS bits according to USART_Parity value */
+ /* Set TE and RE bits according to USART_Mode value */
+ tmpreg |= (uint32_t)USART_InitStruct->USART_WordLength | USART_InitStruct->USART_Parity |
+ USART_InitStruct->USART_Mode;
+
+ /* Write to USART CR1 */
+ USARTx->CR1 = tmpreg;
+
+ /*---------------------------- USART CR3 Configuration -----------------------*/
+ tmpreg = USARTx->CR3;
+ /* Clear CTSE and RTSE bits */
+ tmpreg &= (uint32_t)~((uint32_t)CR3_CLEAR_MASK);
+
+ /* Configure the USART HFC -------------------------------------------------*/
+ /* Set CTSE and RTSE bits according to USART_HardwareFlowControl value */
+ tmpreg |= USART_InitStruct->USART_HardwareFlowControl;
+
+ /* Write to USART CR3 */
+ USARTx->CR3 = tmpreg;
+
+ /*---------------------------- USART BRR Configuration -----------------------*/
+ /* Configure the USART Baud Rate -------------------------------------------*/
+ RCC_GetClocksFreq(&RCC_ClocksStatus);
+
+ if (USARTx == USART1)
+ {
+ apbclock = RCC_ClocksStatus.USART1CLK_Frequency;
+ }
+ else
+ {
+ apbclock = RCC_ClocksStatus.PCLK_Frequency;
+ }
+
+ /* Determine the integer part */
+ if ((USARTx->CR1 & USART_CR1_OVER8) != 0)
+ {
+ /* (divider * 10) computing in case Oversampling mode is 8 Samples */
+ divider = (uint32_t)((2 * apbclock) / (USART_InitStruct->USART_BaudRate));
+ tmpreg = (uint32_t)((2 * apbclock) % (USART_InitStruct->USART_BaudRate));
+ }
+ else /* if ((USARTx->CR1 & CR1_OVER8_Set) == 0) */
+ {
+ /* (divider * 10) computing in case Oversampling mode is 16 Samples */
+ divider = (uint32_t)((apbclock) / (USART_InitStruct->USART_BaudRate));
+ tmpreg = (uint32_t)((apbclock) % (USART_InitStruct->USART_BaudRate));
+ }
+
+ /* round the divider : if fractional part i greater than 0.5 increment divider */
+ if (tmpreg >= (USART_InitStruct->USART_BaudRate) / 2)
+ {
+ divider++;
+ }
+
+ /* Implement the divider in case Oversampling mode is 8 Samples */
+ if ((USARTx->CR1 & USART_CR1_OVER8) != 0)
+ {
+ /* get the LSB of divider and shift it to the right by 1 bit */
+ tmpreg = (divider & (uint16_t)0x000F) >> 1;
+
+ /* update the divider value */
+ divider = (divider & (uint16_t)0xFFF0) | tmpreg;
+ }
+
+ /* Write to USART BRR */
+ USARTx->BRR = (uint16_t)divider;
+}
+
+/**
+ * @brief Fills each USART_InitStruct member with its default value.
+ * @param USART_InitStruct: pointer to a USART_InitTypeDef structure
+ * which will be initialized.
+ * @retval None
+ */
+void USART_StructInit(USART_InitTypeDef* USART_InitStruct)
+{
+ /* USART_InitStruct members default value */
+ USART_InitStruct->USART_BaudRate = 9600;
+ USART_InitStruct->USART_WordLength = USART_WordLength_8b;
+ USART_InitStruct->USART_StopBits = USART_StopBits_1;
+ USART_InitStruct->USART_Parity = USART_Parity_No ;
+ USART_InitStruct->USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
+ USART_InitStruct->USART_HardwareFlowControl = USART_HardwareFlowControl_None;
+}
+
+/**
+ * @brief Initializes the USARTx peripheral Clock according to the
+ * specified parameters in the USART_ClockInitStruct.
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @param USART_ClockInitStruct: pointer to a USART_ClockInitTypeDef
+ * structure that contains the configuration information for the specified
+ * USART peripheral.
+ * @retval None
+ */
+void USART_ClockInit(USART_TypeDef* USARTx, USART_ClockInitTypeDef* USART_ClockInitStruct)
+{
+ uint32_t tmpreg = 0;
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_CLOCK(USART_ClockInitStruct->USART_Clock));
+ assert_param(IS_USART_CPOL(USART_ClockInitStruct->USART_CPOL));
+ assert_param(IS_USART_CPHA(USART_ClockInitStruct->USART_CPHA));
+ assert_param(IS_USART_LASTBIT(USART_ClockInitStruct->USART_LastBit));
+/*---------------------------- USART CR2 Configuration -----------------------*/
+ tmpreg = USARTx->CR2;
+ /* Clear CLKEN, CPOL, CPHA, LBCL and SSM bits */
+ tmpreg &= (uint32_t)~((uint32_t)CR2_CLOCK_CLEAR_MASK);
+ /* Configure the USART Clock, CPOL, CPHA, LastBit and SSM ------------*/
+ /* Set CLKEN bit according to USART_Clock value */
+ /* Set CPOL bit according to USART_CPOL value */
+ /* Set CPHA bit according to USART_CPHA value */
+ /* Set LBCL bit according to USART_LastBit value */
+ tmpreg |= (uint32_t)(USART_ClockInitStruct->USART_Clock | USART_ClockInitStruct->USART_CPOL |
+ USART_ClockInitStruct->USART_CPHA | USART_ClockInitStruct->USART_LastBit);
+ /* Write to USART CR2 */
+ USARTx->CR2 = tmpreg;
+}
+
+/**
+ * @brief Fills each USART_ClockInitStruct member with its default value.
+ * @param USART_ClockInitStruct: pointer to a USART_ClockInitTypeDef
+ * structure which will be initialized.
+ * @retval None
+ */
+void USART_ClockStructInit(USART_ClockInitTypeDef* USART_ClockInitStruct)
+{
+ /* USART_ClockInitStruct members default value */
+ USART_ClockInitStruct->USART_Clock = USART_Clock_Disable;
+ USART_ClockInitStruct->USART_CPOL = USART_CPOL_Low;
+ USART_ClockInitStruct->USART_CPHA = USART_CPHA_1Edge;
+ USART_ClockInitStruct->USART_LastBit = USART_LastBit_Disable;
+}
+
+/**
+ * @brief Enables or disables the specified USART peripheral.
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @param NewState: new state of the USARTx peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected USART by setting the UE bit in the CR1 register */
+ USARTx->CR1 |= USART_CR1_UE;
+ }
+ else
+ {
+ /* Disable the selected USART by clearing the UE bit in the CR1 register */
+ USARTx->CR1 &= (uint32_t)~((uint32_t)USART_CR1_UE);
+ }
+}
+
+/**
+ * @brief Enables or disables the USART's transmitter or receiver.
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @param USART_Direction: specifies the USART direction.
+ * This parameter can be any combination of the following values:
+ * @arg USART_Mode_Tx: USART Transmitter
+ * @arg USART_Mode_Rx: USART Receiver
+ * @param NewState: new state of the USART transfer direction.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void USART_DirectionModeCmd(USART_TypeDef* USARTx, uint32_t USART_DirectionMode, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_MODE(USART_DirectionMode));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the USART's transfer interface by setting the TE and/or RE bits
+ in the USART CR1 register */
+ USARTx->CR1 |= USART_DirectionMode;
+ }
+ else
+ {
+ /* Disable the USART's transfer interface by clearing the TE and/or RE bits
+ in the USART CR3 register */
+ USARTx->CR1 &= (uint32_t)~USART_DirectionMode;
+ }
+}
+
+/**
+ * @brief Enables or disables the USART's 8x oversampling mode.
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @param NewState: new state of the USART 8x oversampling mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @note This function has to be called before calling USART_Init() function
+ * in order to have correct baudrate Divider value.
+ * @retval None
+ */
+void USART_OverSampling8Cmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the 8x Oversampling mode by setting the OVER8 bit in the CR1 register */
+ USARTx->CR1 |= USART_CR1_OVER8;
+ }
+ else
+ {
+ /* Disable the 8x Oversampling mode by clearing the OVER8 bit in the CR1 register */
+ USARTx->CR1 &= (uint32_t)~((uint32_t)USART_CR1_OVER8);
+ }
+}
+
+/**
+ * @brief Enables or disables the USART's one bit sampling method.
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @param NewState: new state of the USART one bit sampling method.
+ * This parameter can be: ENABLE or DISABLE.
+ * @note This function has to be called before calling USART_Cmd() function.
+ * @retval None
+ */
+void USART_OneBitMethodCmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the one bit method by setting the ONEBITE bit in the CR3 register */
+ USARTx->CR3 |= USART_CR3_ONEBIT;
+ }
+ else
+ {
+ /* Disable the one bit method by clearing the ONEBITE bit in the CR3 register */
+ USARTx->CR3 &= (uint32_t)~((uint32_t)USART_CR3_ONEBIT);
+ }
+}
+
+/**
+ * @brief Enables or disables the USART's most significant bit first
+ * transmitted/received following the start bit.
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @param NewState: new state of the USART most significant bit first
+ * transmitted/received following the start bit.
+ * This parameter can be: ENABLE or DISABLE.
+ * @note This function has to be called before calling USART_Cmd() function.
+ * @retval None
+ */
+void USART_MSBFirstCmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the most significant bit first transmitted/received following the
+ start bit by setting the MSBFIRST bit in the CR2 register */
+ USARTx->CR2 |= USART_CR2_MSBFIRST;
+ }
+ else
+ {
+ /* Disable the most significant bit first transmitted/received following the
+ start bit by clearing the MSBFIRST bit in the CR2 register */
+ USARTx->CR2 &= (uint32_t)~((uint32_t)USART_CR2_MSBFIRST);
+ }
+}
+
+/**
+ * @brief Enables or disables the binary data inversion.
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @param NewState: new defined levels for the USART data.
+ * This parameter can be:
+ * @arg ENABLE: Logical data from the data register are send/received in negative
+ * logic (1=L, 0=H). The parity bit is also inverted.
+ * @arg DISABLE: Logical data from the data register are send/received in positive
+ * logic (1=H, 0=L)
+ * @note This function has to be called before calling USART_Cmd() function.
+ * @retval None
+ */
+void USART_DataInvCmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the binary data inversion feature by setting the DATAINV bit in
+ the CR2 register */
+ USARTx->CR2 |= USART_CR2_DATAINV;
+ }
+ else
+ {
+ /* Disable the binary data inversion feature by clearing the DATAINV bit in
+ the CR2 register */
+ USARTx->CR2 &= (uint32_t)~((uint32_t)USART_CR2_DATAINV);
+ }
+}
+
+/**
+ * @brief Enables or disables the Pin(s) active level inversion.
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @param USART_InvPin: specifies the USART pin(s) to invert.
+ * This parameter can be any combination of the following values:
+ * @arg USART_InvPin_Tx: USART Tx pin active level inversion.
+ * @arg USART_InvPin_Rx: USART Rx pin active level inversion.
+ * @param NewState: new active level status for the USART pin(s).
+ * This parameter can be:
+ * @arg ENABLE: pin(s) signal values are inverted (Vdd =0, Gnd =1).
+ * @arg DISABLE: pin(s) signal works using the standard logic levels (Vdd =1, Gnd =0).
+ * @note This function has to be called before calling USART_Cmd() function.
+ * @retval None
+ */
+void USART_InvPinCmd(USART_TypeDef* USARTx, uint32_t USART_InvPin, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_INVERSTION_PIN(USART_InvPin));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the active level inversion for selected pins by setting the TXINV
+ and/or RXINV bits in the USART CR2 register */
+ USARTx->CR2 |= USART_InvPin;
+ }
+ else
+ {
+ /* Disable the active level inversion for selected requests by clearing the
+ TXINV and/or RXINV bits in the USART CR2 register */
+ USARTx->CR2 &= (uint32_t)~USART_InvPin;
+ }
+}
+
+/**
+ * @brief Enables or disables the swap Tx/Rx pins.
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @param NewState: new state of the USARTx TX/RX pins pinout.
+ * This parameter can be:
+ * @arg ENABLE: The TX and RX pins functions are swapped.
+ * @arg DISABLE: TX/RX pins are used as defined in standard pinout
+ * @note This function has to be called before calling USART_Cmd() function.
+ * @retval None
+ */
+void USART_SWAPPinCmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the SWAP feature by setting the SWAP bit in the CR2 register */
+ USARTx->CR2 |= USART_CR2_SWAP;
+ }
+ else
+ {
+ /* Disable the SWAP feature by clearing the SWAP bit in the CR2 register */
+ USARTx->CR2 &= (uint32_t)~((uint32_t)USART_CR2_SWAP);
+ }
+}
+
+/**
+ * @brief Enables or disables the receiver Time Out feature.
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @param NewState: new state of the USARTx receiver Time Out.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void USART_ReceiverTimeOutCmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_1_PERIPH(USARTx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the receiver time out feature by setting the RTOEN bit in the CR2
+ register */
+ USARTx->CR2 |= USART_CR2_RTOEN;
+ }
+ else
+ {
+ /* Disable the receiver time out feature by clearing the RTOEN bit in the CR2
+ register */
+ USARTx->CR2 &= (uint32_t)~((uint32_t)USART_CR2_RTOEN);
+ }
+}
+
+/**
+ * @brief Sets the receiver Time Out value.
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @param USART_ReceiverTimeOut: specifies the Receiver Time Out value.
+ * @retval None
+ */
+void USART_SetReceiverTimeOut(USART_TypeDef* USARTx, uint32_t USART_ReceiverTimeOut)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_1_PERIPH(USARTx));
+ assert_param(IS_USART_TIMEOUT(USART_ReceiverTimeOut));
+
+ /* Clear the receiver Time Out value by clearing the RTO[23:0] bits in the RTOR
+ register */
+ USARTx->RTOR &= (uint32_t)~((uint32_t)USART_RTOR_RTO);
+ /* Set the receiver Time Out value by setting the RTO[23:0] bits in the RTOR
+ register */
+ USARTx->RTOR |= USART_ReceiverTimeOut;
+}
+
+/**
+ * @brief Sets the system clock prescaler.
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @param USART_Prescaler: specifies the prescaler clock.
+ * @note This function has to be called before calling USART_Cmd() function.
+ * @retval None
+ */
+void USART_SetPrescaler(USART_TypeDef* USARTx, uint8_t USART_Prescaler)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_1_PERIPH(USARTx));
+
+ /* Clear the USART prescaler */
+ USARTx->GTPR &= USART_GTPR_GT;
+ /* Set the USART prescaler */
+ USARTx->GTPR |= USART_Prescaler;
+}
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USART_Group2 STOP Mode functions
+ * @brief STOP Mode functions
+ *
+@verbatim
+ ===============================================================================
+ ##### STOP Mode functions #####
+ ===============================================================================
+ [..] This subsection provides a set of functions allowing to manage
+ WakeUp from STOP mode.
+
+ [..] The USART is able to WakeUp from Stop Mode if USART clock is set to HSI
+ or LSI.
+
+ [..] The WakeUp source is configured by calling USART_StopModeWakeUpSourceConfig()
+ function.
+
+ [..] After configuring the source of WakeUp and before entering in Stop Mode
+ USART_STOPModeCmd() function should be called to allow USART WakeUp.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the specified USART peripheral in STOP Mode.
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @param NewState: new state of the USARTx peripheral state in stop mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @note This function has to be called when USART clock is set to HSI or LSE.
+ * @retval None
+ */
+void USART_STOPModeCmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_1_PERIPH(USARTx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected USART in STOP mode by setting the UESM bit in the CR1
+ register */
+ USARTx->CR1 |= USART_CR1_UESM;
+ }
+ else
+ {
+ /* Disable the selected USART in STOP mode by clearing the UE bit in the CR1
+ register */
+ USARTx->CR1 &= (uint32_t)~((uint32_t)USART_CR1_UESM);
+ }
+}
+
+/**
+ * @brief Selects the USART WakeUp method form stop mode.
+ * @param USARTx: where x can be 1 select the USART peripheral.
+ * @param USART_WakeUp: specifies the selected USART wakeup method.
+ * This parameter can be one of the following values:
+ * @arg USART_WakeUpSource_AddressMatch: WUF active on address match.
+ * @arg USART_WakeUpSource_StartBit: WUF active on Start bit detection.
+ * @arg USART_WakeUpSource_RXNE: WUF active on RXNE.
+ * @note This function has to be called before calling USART_Cmd() function.
+ * @retval None
+ */
+void USART_StopModeWakeUpSourceConfig(USART_TypeDef* USARTx, uint32_t USART_WakeUpSource)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_1_PERIPH(USARTx));
+ assert_param(IS_USART_STOPMODE_WAKEUPSOURCE(USART_WakeUpSource));
+
+ USARTx->CR3 &= (uint32_t)~((uint32_t)USART_CR3_WUS);
+ USARTx->CR3 |= USART_WakeUpSource;
+}
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USART_Group3 AutoBaudRate functions
+ * @brief AutoBaudRate functions
+ *
+@verbatim
+ ===============================================================================
+ ##### AutoBaudRate functions #####
+ ===============================================================================
+ [..] This subsection provides a set of functions allowing to manage
+ the AutoBaudRate detections.
+
+ [..] Before Enabling AutoBaudRate detection using USART_AutoBaudRateCmd ()
+ The character patterns used to calculate baudrate must be chosen by calling
+ USART_AutoBaudRateConfig() function. These function take as parameter :
+ (#)USART_AutoBaudRate_StartBit : any character starting with a bit 1.
+ (#)USART_AutoBaudRate_FallingEdge : any character starting with a 10xx bit pattern.
+
+ [..] At any later time, another request for AutoBaudRate detection can be performed
+ using USART_RequestCmd() function.
+
+ [..] The AutoBaudRate detection is monitored by the status of ABRF flag which indicate
+ that the AutoBaudRate detection is completed. In addition to ABRF flag, the ABRE flag
+ indicate that this procedure is completed without success. USART_GetFlagStatus ()
+ function should be used to monitor the status of these flags.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the Auto Baud Rate.
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @param NewState: new state of the USARTx auto baud rate.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void USART_AutoBaudRateCmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_1_PERIPH(USARTx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the auto baud rate feature by setting the ABREN bit in the CR2
+ register */
+ USARTx->CR2 |= USART_CR2_ABREN;
+ }
+ else
+ {
+ /* Disable the auto baud rate feature by clearing the ABREN bit in the CR2
+ register */
+ USARTx->CR2 &= (uint32_t)~((uint32_t)USART_CR2_ABREN);
+ }
+}
+
+/**
+ * @brief Selects the USART auto baud rate method.
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @param USART_AutoBaudRate: specifies the selected USART auto baud rate method.
+ * This parameter can be one of the following values:
+ * @arg USART_AutoBaudRate_StartBit: Start Bit duration measurement.
+ * @arg USART_AutoBaudRate_FallingEdge: Falling edge to falling edge measurement.
+ * @note This function has to be called before calling USART_Cmd() function.
+ * @retval None
+ */
+void USART_AutoBaudRateConfig(USART_TypeDef* USARTx, uint32_t USART_AutoBaudRate)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_1_PERIPH(USARTx));
+ assert_param(IS_USART_AUTOBAUDRATE_MODE(USART_AutoBaudRate));
+
+ USARTx->CR2 &= (uint32_t)~((uint32_t)USART_CR2_ABRMODE);
+ USARTx->CR2 |= USART_AutoBaudRate;
+}
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USART_Group4 Data transfers functions
+ * @brief Data transfers functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Data transfers functions #####
+ ===============================================================================
+ [..] This subsection provides a set of functions allowing to manage
+ the USART data transfers.
+ [..] During an USART reception, data shifts in least significant bit first
+ through the RX pin. When a transmission is taking place, a write instruction to
+ the USART_TDR register stores the data in the shift register.
+ [..] The read access of the USART_RDR register can be done using
+ the USART_ReceiveData() function and returns the RDR value.
+ Whereas a write access to the USART_TDR can be done using USART_SendData()
+ function and stores the written data into TDR.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Transmits single data through the USARTx peripheral.
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @param Data: the data to transmit.
+ * @retval None
+ */
+void USART_SendData(USART_TypeDef* USARTx, uint16_t Data)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_DATA(Data));
+
+ /* Transmit Data */
+ USARTx->TDR = (Data & (uint16_t)0x01FF);
+}
+
+/**
+ * @brief Returns the most recent received data by the USARTx peripheral.
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @retval The received data.
+ */
+uint16_t USART_ReceiveData(USART_TypeDef* USARTx)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+
+ /* Receive Data */
+ return (uint16_t)(USARTx->RDR & (uint16_t)0x01FF);
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_Group5 MultiProcessor Communication functions
+ * @brief Multi-Processor Communication functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Multi-Processor Communication functions #####
+ ===============================================================================
+ [..] This subsection provides a set of functions allowing to manage the USART
+ multiprocessor communication.
+ [..] For instance one of the USARTs can be the master, its TX output is
+ connected to the RX input of the other USART. The others are slaves,
+ their respective TX outputs are logically ANDed together and connected
+ to the RX input of the master. USART multiprocessor communication is
+ possible through the following procedure:
+ (#) Program the Baud rate, Word length = 9 bits, Stop bits, Parity,
+ Mode transmitter or Mode receiver and hardware flow control values
+ using the USART_Init() function.
+ (#) Configures the USART address using the USART_SetAddress() function.
+ (#) Configures the wake up methode (USART_WakeUp_IdleLine or
+ USART_WakeUp_AddressMark) using USART_WakeUpConfig() function only
+ for the slaves.
+ (#) Enable the USART using the USART_Cmd() function.
+ (#) Enter the USART slaves in mute mode using USART_ReceiverWakeUpCmd()
+ function.
+ [..] The USART Slave exit from mute mode when receive the wake up condition.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Sets the address of the USART node.
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @param USART_Address: Indicates the address of the USART node.
+ * @retval None
+ */
+void USART_SetAddress(USART_TypeDef* USARTx, uint8_t USART_Address)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+
+ /* Clear the USART address */
+ USARTx->CR2 &= (uint32_t)~((uint32_t)USART_CR2_ADD);
+ /* Set the USART address node */
+ USARTx->CR2 |=((uint32_t)USART_Address << (uint32_t)0x18);
+}
+
+/**
+ * @brief Enables or disables the USART's mute mode.
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @param NewState: new state of the USART mute mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void USART_MuteModeCmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the USART mute mode by setting the MME bit in the CR1 register */
+ USARTx->CR1 |= USART_CR1_MME;
+ }
+ else
+ {
+ /* Disable the USART mute mode by clearing the MME bit in the CR1 register */
+ USARTx->CR1 &= (uint32_t)~((uint32_t)USART_CR1_MME);
+ }
+}
+
+/**
+ * @brief Selects the USART WakeUp method from mute mode.
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @param USART_WakeUp: specifies the USART wakeup method.
+ * This parameter can be one of the following values:
+ * @arg USART_WakeUp_IdleLine: WakeUp by an idle line detection
+ * @arg USART_WakeUp_AddressMark: WakeUp by an address mark
+ * @retval None
+ */
+void USART_MuteModeWakeUpConfig(USART_TypeDef* USARTx, uint32_t USART_WakeUp)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_MUTEMODE_WAKEUP(USART_WakeUp));
+
+ USARTx->CR1 &= (uint32_t)~((uint32_t)USART_CR1_WAKE);
+ USARTx->CR1 |= USART_WakeUp;
+}
+
+/**
+ * @brief Configure the the USART Address detection length.
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @param USART_AddressLength: specifies the USART address length detection.
+ * This parameter can be one of the following values:
+ * @arg USART_AddressLength_4b: 4-bit address length detection
+ * @arg USART_AddressLength_7b: 7-bit address length detection
+ * @retval None
+ */
+void USART_AddressDetectionConfig(USART_TypeDef* USARTx, uint32_t USART_AddressLength)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_ADDRESS_DETECTION(USART_AddressLength));
+
+ USARTx->CR2 &= (uint32_t)~((uint32_t)USART_CR2_ADDM7);
+ USARTx->CR2 |= USART_AddressLength;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_Group6 LIN mode functions
+ * @brief LIN mode functions
+ *
+@verbatim
+ ===============================================================================
+ ##### LIN mode functions #####
+ ===============================================================================
+ [..] This subsection provides a set of functions allowing to manage the USART
+ LIN Mode communication.
+ [..] In LIN mode, 8-bit data format with 1 stop bit is required in accordance
+ with the LIN standard.
+ [..] Only this LIN Feature is supported by the USART IP:
+ (+) LIN Master Synchronous Break send capability and LIN slave break
+ detection capability : 13-bit break generation and 10/11 bit break
+ detection.
+ [..] USART LIN Master transmitter communication is possible through the
+ following procedure:
+ (#) Program the Baud rate, Word length = 8bits, Stop bits = 1bit, Parity,
+ Mode transmitter or Mode receiver and hardware flow control values
+ using the USART_Init() function.
+ (#) Enable the LIN mode using the USART_LINCmd() function.
+ (#) Enable the USART using the USART_Cmd() function.
+ (#) Send the break character using USART_SendBreak() function.
+ [..] USART LIN Master receiver communication is possible through the
+ following procedure:
+ (#) Program the Baud rate, Word length = 8bits, Stop bits = 1bit, Parity,
+ Mode transmitter or Mode receiver and hardware flow control values
+ using the USART_Init() function.
+ (#) Configures the break detection length
+ using the USART_LINBreakDetectLengthConfig() function.
+ (#) Enable the LIN mode using the USART_LINCmd() function.
+ -@- In LIN mode, the following bits must be kept cleared:
+ (+@) CLKEN in the USART_CR2 register.
+ (+@) STOP[1:0], SCEN, HDSEL and IREN in the USART_CR3 register.
+ (#) Enable the USART using the USART_Cmd() function.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Sets the USART LIN Break detection length.
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @param USART_LINBreakDetectLength: specifies the LIN break detection length.
+ * This parameter can be one of the following values:
+ * @arg USART_LINBreakDetectLength_10b: 10-bit break detection
+ * @arg USART_LINBreakDetectLength_11b: 11-bit break detection
+ * @retval None
+ */
+void USART_LINBreakDetectLengthConfig(USART_TypeDef* USARTx, uint32_t USART_LINBreakDetectLength)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_1_PERIPH(USARTx));
+ assert_param(IS_USART_LIN_BREAK_DETECT_LENGTH(USART_LINBreakDetectLength));
+
+ USARTx->CR2 &= (uint32_t)~((uint32_t)USART_CR2_LBDL);
+ USARTx->CR2 |= USART_LINBreakDetectLength;
+}
+
+/**
+ * @brief Enables or disables the USART's LIN mode.
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @param NewState: new state of the USART LIN mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void USART_LINCmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_1_PERIPH(USARTx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the LIN mode by setting the LINEN bit in the CR2 register */
+ USARTx->CR2 |= USART_CR2_LINEN;
+ }
+ else
+ {
+ /* Disable the LIN mode by clearing the LINEN bit in the CR2 register */
+ USARTx->CR2 &= (uint32_t)~((uint32_t)USART_CR2_LINEN);
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_Group7 Halfduplex mode function
+ * @brief Half-duplex mode function
+ *
+@verbatim
+ ===============================================================================
+ ##### Half-duplex mode function #####
+ ===============================================================================
+ [..] This subsection provides a set of functions allowing to manage the USART
+ Half-duplex communication.
+ [..] The USART can be configured to follow a single-wire half-duplex protocol
+ where the TX and RX lines are internally connected.
+ [..] USART Half duplex communication is possible through the following procedure:
+ (#) Program the Baud rate, Word length, Stop bits, Parity, Mode transmitter
+ or Mode receiver and hardware flow control values using the USART_Init()
+ function.
+ (#) Configures the USART address using the USART_SetAddress() function.
+ (#) Enable the half duplex mode using USART_HalfDuplexCmd() function.
+ (#) Enable the USART using the USART_Cmd() function.
+ -@- The RX pin is no longer used.
+ -@- 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.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the USART's Half Duplex communication.
+ * @param USARTx: where x can be 1to select the USART peripheral.
+ * @param NewState: new state of the USART Communication.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void USART_HalfDuplexCmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */
+ USARTx->CR3 |= USART_CR3_HDSEL;
+ }
+ else
+ {
+ /* Disable the Half-Duplex mode by clearing the HDSEL bit in the CR3 register */
+ USARTx->CR3 &= (uint32_t)~((uint32_t)USART_CR3_HDSEL);
+ }
+}
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USART_Group8 Smartcard mode functions
+ * @brief Smartcard mode functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Smartcard mode functions #####
+ ===============================================================================
+ [..] This subsection provides a set of functions allowing to manage the USART
+ Smartcard communication.
+ [..] 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.
+ [..] Smartcard communication is possible through the following procedure:
+ (#) Configures the Smartcard Prsecaler using the USART_SetPrescaler()
+ function.
+ (#) Configures the Smartcard Guard Time using the USART_SetGuardTime()
+ function.
+ (#) Program the USART clock using the USART_ClockInit() function as following:
+ (++) USART Clock enabled.
+ (++) USART CPOL Low.
+ (++) USART CPHA on first edge.
+ (++) USART Last Bit Clock Enabled.
+ (#) Program the Smartcard interface using the USART_Init() function as
+ following:
+ (++) Word Length = 9 Bits.
+ (++) 1.5 Stop Bit.
+ (++) Even parity.
+ (++) BaudRate = 12096 baud.
+ (++) Hardware flow control disabled (RTS and CTS signals).
+ (++) Tx and Rx enabled
+ (#) Optionally you can enable the parity error interrupt using
+ the USART_ITConfig() function.
+ (#) Enable the Smartcard NACK using the USART_SmartCardNACKCmd() function.
+ (#) Enable the Smartcard interface using the USART_SmartCardCmd() function.
+ (#) Enable the USART using the USART_Cmd() function.
+ [..]
+ 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.
+ (@) 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.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Sets the specified USART guard time.
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @param USART_GuardTime: specifies the guard time.
+ * @retval None
+ */
+void USART_SetGuardTime(USART_TypeDef* USARTx, uint8_t USART_GuardTime)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_1_PERIPH(USARTx));
+
+ /* Clear the USART Guard time */
+ USARTx->GTPR &= USART_GTPR_PSC;
+ /* Set the USART guard time */
+ USARTx->GTPR |= (uint16_t)((uint16_t)USART_GuardTime << 0x08);
+}
+
+/**
+ * @brief Enables or disables the USART's Smart Card mode.
+ * @param USARTx: where x can be 1 select the USART peripheral.
+ * @param NewState: new state of the Smart Card mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void USART_SmartCardCmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_1_PERIPH(USARTx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the SC mode by setting the SCEN bit in the CR3 register */
+ USARTx->CR3 |= USART_CR3_SCEN;
+ }
+ else
+ {
+ /* Disable the SC mode by clearing the SCEN bit in the CR3 register */
+ USARTx->CR3 &= (uint32_t)~((uint32_t)USART_CR3_SCEN);
+ }
+}
+
+/**
+ * @brief Enables or disables NACK transmission.
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @param NewState: new state of the NACK transmission.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void USART_SmartCardNACKCmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_1_PERIPH(USARTx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the NACK transmission by setting the NACK bit in the CR3 register */
+ USARTx->CR3 |= USART_CR3_NACK;
+ }
+ else
+ {
+ /* Disable the NACK transmission by clearing the NACK bit in the CR3 register */
+ USARTx->CR3 &= (uint32_t)~((uint32_t)USART_CR3_NACK);
+ }
+}
+
+/**
+ * @brief Sets the Smart Card number of retries in transmit and receive.
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @param USART_AutoCount: specifies the Smart Card auto retry count.
+ * @retval None
+ */
+void USART_SetAutoRetryCount(USART_TypeDef* USARTx, uint8_t USART_AutoCount)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_1_PERIPH(USARTx));
+ assert_param(IS_USART_AUTO_RETRY_COUNTER(USART_AutoCount));
+ /* Clear the USART auto retry count */
+ USARTx->CR3 &= (uint32_t)~((uint32_t)USART_CR3_SCARCNT);
+ /* Set the USART auto retry count*/
+ USARTx->CR3 |= (uint32_t)((uint32_t)USART_AutoCount << 0x11);
+}
+
+/**
+ * @brief Sets the Smart Card Block length.
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @param USART_BlockLength: specifies the Smart Card block length.
+ * @retval None
+ */
+void USART_SetBlockLength(USART_TypeDef* USARTx, uint8_t USART_BlockLength)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_1_PERIPH(USARTx));
+
+ /* Clear the Smart card block length */
+ USARTx->RTOR &= (uint32_t)~((uint32_t)USART_RTOR_BLEN);
+ /* Set the Smart Card block length */
+ USARTx->RTOR |= (uint32_t)((uint32_t)USART_BlockLength << 0x18);
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_Group9 IrDA mode functions
+ * @brief IrDA mode functions
+ *
+@verbatim
+ ===============================================================================
+ ##### IrDA mode functions #####
+ ===============================================================================
+ [..] This subsection provides a set of functions allowing to manage the USART
+ IrDA communication.
+ [..] 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.
+ [..] IrDA communication is possible through the following procedure:
+ (#) Program the Baud rate, Word length = 8 bits, Stop bits, Parity,
+ Transmitter/Receiver modes and hardware flow control values using
+ the USART_Init() function.
+ (#) Configures the IrDA pulse width by configuring the prescaler using
+ the USART_SetPrescaler() function.
+ (#) Configures the IrDA USART_IrDAMode_LowPower or USART_IrDAMode_Normal
+ mode using the USART_IrDAConfig() function.
+ (#) Enable the IrDA using the USART_IrDACmd() function.
+ (#) Enable the USART using the USART_Cmd() function.
+ [..]
+ (@) 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).
+ (@) 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.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Configures the USART's IrDA interface.
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @param USART_IrDAMode: specifies the IrDA mode.
+ * This parameter can be one of the following values:
+ * @arg USART_IrDAMode_LowPower
+ * @arg USART_IrDAMode_Normal
+ * @retval None
+ */
+void USART_IrDAConfig(USART_TypeDef* USARTx, uint32_t USART_IrDAMode)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_1_PERIPH(USARTx));
+ assert_param(IS_USART_IRDA_MODE(USART_IrDAMode));
+
+ USARTx->CR3 &= (uint32_t)~((uint32_t)USART_CR3_IRLP);
+ USARTx->CR3 |= USART_IrDAMode;
+}
+
+/**
+ * @brief Enables or disables the USART's IrDA interface.
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @param NewState: new state of the IrDA mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void USART_IrDACmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_1_PERIPH(USARTx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the IrDA mode by setting the IREN bit in the CR3 register */
+ USARTx->CR3 |= USART_CR3_IREN;
+ }
+ else
+ {
+ /* Disable the IrDA mode by clearing the IREN bit in the CR3 register */
+ USARTx->CR3 &= (uint32_t)~((uint32_t)USART_CR3_IREN);
+ }
+}
+/**
+ * @}
+ */
+
+/** @defgroup USART_Group10 RS485 mode function
+ * @brief RS485 mode function
+ *
+@verbatim
+ ===============================================================================
+ ##### RS485 mode functions #####
+ ===============================================================================
+ [..] This subsection provides a set of functions allowing to manage the USART
+ RS485 flow control.
+ [..] RS485 flow control (Driver enable feature) handling is possible through
+ the following procedure:
+ (#) Program the Baud rate, Word length = 8 bits, Stop bits, Parity,
+ Transmitter/Receiver modes and hardware flow control values using
+ the USART_Init() function.
+ (#) Enable the Driver Enable using the USART_DECmd() function.
+ (#) Configures the Driver Enable polarity using the USART_DEPolarityConfig()
+ function.
+ (#) Configures the Driver Enable assertion time using USART_SetDEAssertionTime()
+ function and deassertion time using the USART_SetDEDeassertionTime()
+ function.
+ (#) Enable the USART using the USART_Cmd() function.
+ -@-
+ (+@) The assertion and dessertion times are expressed in sample time units (1/8 or
+ 1/16 bit time, depending on the oversampling rate).
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the USART's DE functionality.
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @param NewState: new state of the driver enable mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void USART_DECmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the DE functionality by setting the DEM bit in the CR3 register */
+ USARTx->CR3 |= USART_CR3_DEM;
+ }
+ else
+ {
+ /* Disable the DE functionality by clearing the DEM bit in the CR3 register */
+ USARTx->CR3 &= (uint32_t)~((uint32_t)USART_CR3_DEM);
+ }
+}
+
+/**
+ * @brief Configures the USART's DE polarity
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @param USART_DEPolarity: specifies the DE polarity.
+ * This parameter can be one of the following values:
+ * @arg USART_DEPolarity_Low
+ * @arg USART_DEPolarity_High
+ * @retval None
+ */
+void USART_DEPolarityConfig(USART_TypeDef* USARTx, uint32_t USART_DEPolarity)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_DE_POLARITY(USART_DEPolarity));
+
+ USARTx->CR3 &= (uint32_t)~((uint32_t)USART_CR3_DEP);
+ USARTx->CR3 |= USART_DEPolarity;
+}
+
+/**
+ * @brief Sets the specified RS485 DE assertion time
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @param USART_DEAssertionTime: specifies the time between the activation of
+ * the DE signal and the beginning of the start bit
+ * @retval None
+ */
+void USART_SetDEAssertionTime(USART_TypeDef* USARTx, uint32_t USART_DEAssertionTime)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_DE_ASSERTION_DEASSERTION_TIME(USART_DEAssertionTime));
+
+ /* Clear the DE assertion time */
+ USARTx->CR1 &= (uint32_t)~((uint32_t)USART_CR1_DEAT);
+ /* Set the new value for the DE assertion time */
+ USARTx->CR1 |=((uint32_t)USART_DEAssertionTime << (uint32_t)0x15);
+}
+
+/**
+ * @brief Sets the specified RS485 DE deassertion time
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @param USART_DeassertionTime: specifies the time between the middle of the last
+ * stop bit in a transmitted message and the de-activation of the DE signal
+ * @retval None
+ */
+void USART_SetDEDeassertionTime(USART_TypeDef* USARTx, uint32_t USART_DEDeassertionTime)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_DE_ASSERTION_DEASSERTION_TIME(USART_DEDeassertionTime));
+
+ /* Clear the DE deassertion time */
+ USARTx->CR1 &= (uint32_t)~((uint32_t)USART_CR1_DEDT);
+ /* Set the new value for the DE deassertion time */
+ USARTx->CR1 |=((uint32_t)USART_DEDeassertionTime << (uint32_t)0x10);
+}
+
+/**
+ * @}
+ */
+
+
+
+/** @defgroup USART_Group12 Interrupts and flags management functions
+ * @brief Interrupts and flags management functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Interrupts and flags management functions #####
+ ===============================================================================
+ [..] This subsection provides a set of functions allowing to configure the
+ USART Interrupts sources, Requests and check or clear the flags or pending bits status.
+ The user should identify which mode will be used in his application to
+ manage the communication: Polling mode, Interrupt mode.
+
+ *** Polling Mode ***
+ ====================
+ [..] In Polling Mode, the SPI communication can be managed by these flags:
+ (#) USART_FLAG_REACK: to indicate the status of the Receive Enable
+ acknowledge flag
+ (#) USART_FLAG_TEACK: to indicate the status of the Transmit Enable
+ acknowledge flag.
+ (#) USART_FLAG_WU: to indicate the status of the Wake up flag.
+ (#) USART_FLAG_RWU: to indicate the status of the Receive Wake up flag.
+ (#) USART_FLAG_SBK: to indicate the status of the Send Break flag.
+ (#) USART_FLAG_CM: to indicate the status of the Character match flag.
+ (#) USART_FLAG_BUSY: to indicate the status of the Busy flag.
+ (#) USART_FLAG_ABRF: to indicate the status of the Auto baud rate flag.
+ (#) USART_FLAG_ABRE: to indicate the status of the Auto baud rate error flag.
+ (#) USART_FLAG_EOB: to indicate the status of the End of block flag.
+ (#) USART_FLAG_RTO: to indicate the status of the Receive time out flag.
+ (#) USART_FLAG_nCTSS: to indicate the status of the Inverted nCTS input
+ bit status.
+ (#) USART_FLAG_TXE: to indicate the status of the transmit buffer register.
+ (#) USART_FLAG_RXNE: to indicate the status of the receive buffer register.
+ (#) USART_FLAG_TC: to indicate the status of the transmit operation.
+ (#) USART_FLAG_IDLE: to indicate the status of the Idle Line.
+ (#) USART_FLAG_CTS: to indicate the status of the nCTS input.
+ (#) USART_FLAG_LBD: to indicate the status of the LIN break detection.
+ (#) USART_FLAG_NE: to indicate if a noise error occur.
+ (#) USART_FLAG_FE: to indicate if a frame error occur.
+ (#) USART_FLAG_PE: to indicate if a parity error occur.
+ (#) USART_FLAG_ORE: to indicate if an Overrun error occur.
+ [..] In this Mode it is advised to use the following functions:
+ (+) FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG).
+ (+) void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG).
+
+ *** Interrupt Mode ***
+ ======================
+ [..] In Interrupt Mode, the USART communication can be managed by 8 interrupt
+ sources and 10 pending bits:
+ (+) Pending Bits:
+ (##) USART_IT_WU: to indicate the status of the Wake up interrupt.
+ (##) USART_IT_CM: to indicate the status of Character match interrupt.
+ (##) USART_IT_EOB: to indicate the status of End of block interrupt.
+ (##) USART_IT_RTO: to indicate the status of Receive time out interrupt.
+ (##) USART_IT_CTS: to indicate the status of CTS change interrupt.
+ (##) USART_IT_LBD: to indicate the status of LIN Break detection interrupt.
+ (##) USART_IT_TC: to indicate the status of Transmission complete interrupt.
+ (##) USART_IT_IDLE: to indicate the status of IDLE line detected interrupt.
+ (##) USART_IT_ORE: to indicate the status of OverRun Error interrupt.
+ (##) USART_IT_NE: to indicate the status of Noise Error interrupt.
+ (##) USART_IT_FE: to indicate the status of Framing Error interrupt.
+ (##) USART_IT_PE: to indicate the status of Parity Error interrupt.
+
+ (+) Interrupt Source:
+ (##) USART_IT_WU: specifies the interrupt source for Wake up interrupt.
+ (##) USART_IT_CM: specifies the interrupt source for Character match
+ interrupt.
+ (##) USART_IT_EOB: specifies the interrupt source for End of block
+ interrupt.
+ (##) USART_IT_RTO: specifies the interrupt source for Receive time-out
+ interrupt.
+ (##) USART_IT_CTS: specifies the interrupt source for CTS change interrupt.
+ (##) USART_IT_LBD: specifies the interrupt source for LIN Break
+ detection interrupt.
+ (##) USART_IT_TXE: specifies the interrupt source for Tansmit Data
+ Register empty interrupt.
+ (##) USART_IT_TC: specifies the interrupt source for Transmission
+ complete interrupt.
+ (##) USART_IT_RXNE: specifies the interrupt source for Receive Data
+ register not empty interrupt.
+ (##) USART_IT_IDLE: specifies the interrupt source for Idle line
+ detection interrupt.
+ (##) USART_IT_PE: specifies the interrupt source for Parity Error interrupt.
+ (##) USART_IT_ERR: specifies the interrupt source for Error interrupt
+ (Frame error, noise error, overrun error)
+ -@@- Some parameters are coded in order to use them as interrupt
+ source or as pending bits.
+ [..] In this Mode it is advised to use the following functions:
+ (+) void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState).
+ (+) ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT).
+ (+) void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT).
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the specified USART interrupts.
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @param USART_IT: specifies the USART interrupt sources to be enabled or disabled.
+ * This parameter can be one of the following values:
+ * @arg USART_IT_WU: Wake up interrupt
+ * @arg USART_IT_CM: Character match interrupt.
+ * @arg USART_IT_EOB: End of block interrupt
+ * @arg USART_IT_RTO: Receive time out interrupt.
+ * @arg USART_IT_CTS: CTS change interrupt.
+ * @arg USART_IT_LBD: LIN Break detection interrupt
+ * @arg USART_IT_TXE: Tansmit Data Register empty interrupt.
+ * @arg USART_IT_TC: Transmission complete interrupt.
+ * @arg USART_IT_RXNE: Receive Data register not empty interrupt.
+ * @arg USART_IT_IDLE: Idle line detection interrupt.
+ * @arg USART_IT_PE: Parity Error interrupt.
+ * @arg USART_IT_ERR: Error interrupt(Frame error, noise error, overrun error)
+ * @param NewState: new state of the specified USARTx interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void USART_ITConfig(USART_TypeDef* USARTx, uint32_t USART_IT, FunctionalState NewState)
+{
+ uint32_t usartreg = 0, itpos = 0, itmask = 0;
+ uint32_t usartxbase = 0;
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_CONFIG_IT(USART_IT));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ usartxbase = (uint32_t)USARTx;
+
+ /* Get the USART register index */
+ usartreg = (((uint16_t)USART_IT) >> 0x08);
+
+ /* Get the interrupt position */
+ itpos = USART_IT & IT_MASK;
+ itmask = (((uint32_t)0x01) << itpos);
+
+ if (usartreg == 0x02) /* The IT is in CR2 register */
+ {
+ usartxbase += 0x04;
+ }
+ else if (usartreg == 0x03) /* The IT is in CR3 register */
+ {
+ usartxbase += 0x08;
+ }
+ else /* The IT is in CR1 register */
+ {
+ }
+ if (NewState != DISABLE)
+ {
+ *(__IO uint32_t*)usartxbase |= itmask;
+ }
+ else
+ {
+ *(__IO uint32_t*)usartxbase &= ~itmask;
+ }
+}
+
+/**
+ * @brief Enables the specified USART's Request.
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @param USART_Request: specifies the USART request.
+ * This parameter can be any combination of the following values:
+ * @arg USART_Request_TXFRQ: Transmit data flush ReQuest
+ * @arg USART_Request_RXFRQ: Receive data flush ReQuest
+ * @arg USART_Request_MMRQ: Mute Mode ReQuest
+ * @arg USART_Request_SBKRQ: Send Break ReQuest
+ * @arg USART_Request_ABRRQ: Auto Baud Rate ReQuest
+ * @param NewState: new state of the USART ReQuest when reception error occurs.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void USART_RequestCmd(USART_TypeDef* USARTx, uint32_t USART_Request, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_REQUEST(USART_Request));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the USART ReQuest by setting the dedicated request bit in the RQR
+ register.*/
+ USARTx->RQR |= USART_Request;
+ }
+ else
+ {
+ /* Disable the USART ReQuest by clearing the dedicated request bit in the RQR
+ register.*/
+ USARTx->RQR &= (uint32_t)~USART_Request;
+ }
+}
+
+/**
+ * @brief Enables or disables the USART's Overrun detection.
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @param USART_OVRDetection: specifies the OVR detection status in case of OVR error.
+ * This parameter can be any combination of the following values:
+ * @arg USART_OVRDetection_Enable: OVR error detection enabled when
+ * the USART OVR error is asserted.
+ * @arg USART_OVRDetection_Disable: OVR error detection disabled when
+ * the USART OVR error is asserted.
+ * @retval None
+ */
+void USART_OverrunDetectionConfig(USART_TypeDef* USARTx, uint32_t USART_OVRDetection)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_OVRDETECTION(USART_OVRDetection));
+
+ /* Clear the OVR detection bit */
+ USARTx->CR3 &= (uint32_t)~((uint32_t)USART_CR3_OVRDIS);
+ /* Set the new value for the OVR detection bit */
+ USARTx->CR3 |= USART_OVRDetection;
+}
+
+/**
+ * @brief Checks whether the specified USART flag is set or not.
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @param USART_FLAG: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg USART_FLAG_REACK: Receive Enable acknowledge flag.
+ * @arg USART_FLAG_TEACK: Transmit Enable acknowledge flag.
+ * @arg USART_FLAG_WU: Wake up flag
+ * @arg USART_FLAG_RWU: Receive Wake up flag
+ * @arg USART_FLAG_SBK: Send Break flag.
+ * @arg USART_FLAG_CM: Character match flag.
+ * @arg USART_FLAG_BUSY: Busy flag.
+ * @arg USART_FLAG_ABRF: Auto baud rate flag.
+ * @arg USART_FLAG_ABRE: Auto baud rate error flag.
+ * @arg USART_FLAG_EOB: End of block flag
+ * @arg USART_FLAG_RTO: Receive time out flag.
+ * @arg USART_FLAG_nCTSS: Inverted nCTS input bit status.
+ * @arg USART_FLAG_CTS: CTS Change flag.
+ * @arg USART_FLAG_LBD: LIN Break detection flag
+ * @arg USART_FLAG_TXE: Transmit data register empty flag.
+ * @arg USART_FLAG_TC: Transmission Complete flag.
+ * @arg USART_FLAG_RXNE: Receive data register not empty flag.
+ * @arg USART_FLAG_IDLE: Idle Line detection flag.
+ * @arg USART_FLAG_ORE: OverRun Error flag.
+ * @arg USART_FLAG_NE: Noise Error flag.
+ * @arg USART_FLAG_FE: Framing Error flag.
+ * @arg USART_FLAG_PE: Parity Error flag.
+ * @retval The new state of USART_FLAG (SET or RESET).
+ */
+FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint32_t USART_FLAG)
+{
+ FlagStatus bitstatus = RESET;
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_FLAG(USART_FLAG));
+
+ if ((USARTx->ISR & USART_FLAG) != (uint16_t)RESET)
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the USARTx's pending flags.
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @param USART_FLAG: specifies the flag to clear.
+ * This parameter can be any combination of the following values:
+ * @arg USART_FLAG_WU: Wake up flag
+ * @arg USART_FLAG_CM: Character match flag.
+ * @arg USART_FLAG_EOB: End of block flag
+ * @arg USART_FLAG_RTO: Receive time out flag.
+ * @arg USART_FLAG_CTS: CTS Change flag.
+ * @arg USART_FLAG_LBD: LIN Break detection flag
+ * @arg USART_FLAG_TC: Transmission Complete flag.
+ * @arg USART_FLAG_IDLE: IDLE line detected 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 Errorflag.
+ *
+ * @note RXNE pending bit is cleared by a read to the USART_RDR register
+ * (USART_ReceiveData()) or by writing 1 to the RXFRQ in the register
+ * USART_RQR (USART_RequestCmd()).
+ * @note TC flag can be also cleared by software sequence: a read operation
+ * to USART_SR register (USART_GetFlagStatus()) followed by a write
+ * operation to USART_TDR register (USART_SendData()).
+ * @note TXE flag is cleared by a write to the USART_TDR register (USART_SendData())
+ * or by writing 1 to the TXFRQ in the register USART_RQR (USART_RequestCmd()).
+ * @note SBKF flag is cleared by 1 to the SBKRQ in the register USART_RQR
+ * (USART_RequestCmd()).
+ * @retval None
+ */
+void USART_ClearFlag(USART_TypeDef* USARTx, uint32_t USART_FLAG)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_CLEAR_FLAG(USART_FLAG));
+
+ USARTx->ICR = USART_FLAG;
+}
+
+/**
+ * @brief Checks whether the specified USART interrupt has occurred or not.
+ * @param USARTx: where x can be 1 to select the USART peripheral.
+ * @param USART_IT: specifies the USART interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg USART_IT_WU: Wake up interrupt
+ * @arg USART_IT_CM: Character match interrupt.
+ * @arg USART_IT_EOB: End of block interrupt
+ * @arg USART_IT_RTO: Receive time out interrupt.
+ * @arg USART_IT_CTS: CTS change interrupt.
+ * @arg USART_IT_LBD: LIN Break detection interrupt
+ * @arg USART_IT_TXE: Tansmit Data Register empty interrupt.
+ * @arg USART_IT_TC: Transmission complete interrupt.
+ * @arg USART_IT_RXNE: Receive Data register not empty interrupt.
+ * @arg USART_IT_IDLE: Idle line detection interrupt.
+ * @arg USART_IT_ORE: OverRun Error interrupt.
+ * @arg USART_IT_NE: Noise Error interrupt.
+ * @arg USART_IT_FE: Framing Error interrupt.
+ * @arg USART_IT_PE: Parity Error interrupt.
+ * @retval The new state of USART_IT (SET or RESET).
+ */
+ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint32_t USART_IT)
+{
+ uint32_t bitpos = 0, itmask = 0, usartreg = 0;
+ ITStatus bitstatus = RESET;
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_GET_IT(USART_IT));
+
+ /* Get the USART register index */
+ usartreg = (((uint16_t)USART_IT) >> 0x08);
+ /* Get the interrupt position */
+ itmask = USART_IT & IT_MASK;
+ itmask = (uint32_t)0x01 << itmask;
+
+ if (usartreg == 0x01) /* The IT is in CR1 register */
+ {
+ itmask &= USARTx->CR1;
+ }
+ else if (usartreg == 0x02) /* The IT is in CR2 register */
+ {
+ itmask &= USARTx->CR2;
+ }
+ else /* The IT is in CR3 register */
+ {
+ itmask &= USARTx->CR3;
+ }
+
+ bitpos = USART_IT >> 0x10;
+ bitpos = (uint32_t)0x01 << bitpos;
+ bitpos &= USARTx->ISR;
+ if ((itmask != (uint16_t)RESET)&&(bitpos != (uint16_t)RESET))
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the USARTx's interrupt pending bits.
+ * @param USARTx: where x can 1 to select the USART peripheral.
+ * @param USART_IT: specifies the interrupt pending bit to clear.
+ * This parameter can be one of the following values:
+ * @arg USART_IT_WU: Wake up interrupt
+ * @arg USART_IT_CM: Character match interrupt.
+ * @arg USART_IT_EOB: End of block interrupt
+ * @arg USART_IT_RTO: Receive time out interrupt.
+ * @arg USART_IT_CTS: CTS change interrupt.
+ * @arg USART_IT_LBD: LIN Break detection interrupt
+ * @arg USART_IT_TC: Transmission complete interrupt.
+ * @arg USART_IT_IDLE: IDLE line detected interrupt.
+ * @arg USART_IT_ORE: OverRun Error interrupt.
+ * @arg USART_IT_NE: Noise Error interrupt.
+ * @arg USART_IT_FE: Framing Error interrupt.
+ * @arg USART_IT_PE: Parity Error interrupt.
+ *
+ * @note RXNE pending bit is cleared by a read to the USART_RDR register
+ * (USART_ReceiveData()) or by writing 1 to the RXFRQ in the register
+ * USART_RQR (USART_RequestCmd()).
+ * @note TC pending bit can be also cleared by software sequence: a read
+ * operation to USART_SR register (USART_GetITStatus()) followed by
+ * a write operation to USART_TDR register (USART_SendData()).
+ * @note TXE pending bit is cleared by a write to the USART_TDR register
+ * (USART_SendData()) or by writing 1 to the TXFRQ in the register
+ * USART_RQR (USART_RequestCmd()).
+ * @retval None
+ */
+void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint32_t USART_IT)
+{
+ uint32_t bitpos = 0, itmask = 0;
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_CLEAR_IT(USART_IT));
+
+ bitpos = USART_IT >> 0x10;
+ itmask = ((uint32_t)0x01 << (uint32_t)bitpos);
+ USARTx->ICR = (uint32_t)itmask;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_wwdg.c b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_wwdg.c
new file mode 100644
index 0000000..e5c43ab
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/driver/HK32F030M_Driver/src/hk32f030m_wwdg.c
@@ -0,0 +1,219 @@
+/**
+ ******************************************************************************
+ * @file hk32f030m_wwdg.c
+ * @version V1.0.1
+ * author Rakan.Z/wing.Wang
+ * @date 2019-08-15
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "hk32f030m_wwdg.h"
+#include "hk32f030m_rcc.h"
+
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* --------------------- WWDG registers bit mask ---------------------------- */
+/* CFR register bit mask */
+#define CFR_WDGTB_MASK ((uint32_t)0xFFFFFE7F)
+#define CFR_W_MASK ((uint32_t)0xFFFFFF80)
+#define BIT_MASK ((uint8_t)0x7F)
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup WWDG_Private_Functions
+ * @{
+ */
+
+/** @defgroup WWDG_Group1 Prescaler, Refresh window and Counter configuration functions
+ * @brief Prescaler, Refresh window and Counter configuration functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Prescaler, Refresh window and Counter configuration functions #####
+ ==============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Deinitializes the WWDG peripheral registers to their default reset values.
+ * @param None
+ * @retval None
+ */
+void WWDG_DeInit(void)
+{
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_WWDG, ENABLE);
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_WWDG, DISABLE);
+}
+
+/**
+ * @brief Sets the WWDG Prescaler.
+ * @param WWDG_Prescaler: specifies the WWDG Prescaler.
+ * This parameter can be one of the following values:
+ * @arg WWDG_Prescaler_1: WWDG counter clock = (PCLK1/4096)/1
+ * @arg WWDG_Prescaler_2: WWDG counter clock = (PCLK1/4096)/2
+ * @arg WWDG_Prescaler_4: WWDG counter clock = (PCLK1/4096)/4
+ * @arg WWDG_Prescaler_8: WWDG counter clock = (PCLK1/4096)/8
+ * @retval None
+ */
+void WWDG_SetPrescaler(uint32_t WWDG_Prescaler)
+{
+ uint32_t tmpreg = 0;
+ /* Check the parameters */
+ assert_param(IS_WWDG_PRESCALER(WWDG_Prescaler));
+ /* Clear WDGTB[1:0] bits */
+ tmpreg = WWDG->CFR & CFR_WDGTB_MASK;
+ /* Set WDGTB[1:0] bits according to WWDG_Prescaler value */
+ tmpreg |= WWDG_Prescaler;
+ /* Store the new value */
+ WWDG->CFR = tmpreg;
+}
+
+/**
+ * @brief Sets the WWDG window value.
+ * @param WindowValue: specifies the window value to be compared to the downcounter.
+ * This parameter value must be lower than 0x80.
+ * @retval None
+ */
+void WWDG_SetWindowValue(uint8_t WindowValue)
+{
+ __IO uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_WWDG_WINDOW_VALUE(WindowValue));
+ /* Clear W[6:0] bits */
+
+ tmpreg = WWDG->CFR & CFR_W_MASK;
+
+ /* Set W[6:0] bits according to WindowValue value */
+ tmpreg |= WindowValue & (uint32_t) BIT_MASK;
+
+ /* Store the new value */
+ WWDG->CFR = tmpreg;
+}
+
+/**
+ * @brief Enables the WWDG Early Wakeup interrupt(EWI).
+ * @note Once enabled this interrupt cannot be disabled except by a system reset.
+ * @param None
+ * @retval None
+ */
+void WWDG_EnableIT(void)
+{
+ WWDG->CFR |= WWDG_CFR_EWI;
+}
+
+/**
+ * @brief Sets the WWDG counter value.
+ * @param Counter: specifies the watchdog counter value.
+ * This parameter must be a number between 0x40 and 0x7F (to prevent
+ * generating an immediate reset).
+ * @retval None
+ */
+void WWDG_SetCounter(uint8_t Counter)
+{
+ /* Check the parameters */
+ assert_param(IS_WWDG_COUNTER(Counter));
+ /* Write to T[6:0] bits to configure the counter value, no need to do
+ a read-modify-write; writing a 0 to WDGA bit does nothing */
+ WWDG->CR = Counter & BIT_MASK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup WWDG_Group2 WWDG activation functions
+ * @brief WWDG activation functions
+ *
+@verbatim
+ ==============================================================================
+ ##### WWDG activation function #####
+ ==============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables WWDG and load the counter value.
+ * @param Counter: specifies the watchdog counter value.
+ * This parameter must be a number between 0x40 and 0x7F (to prevent
+ * generating an immediate reset).
+ * @retval None
+ */
+void WWDG_Enable(uint8_t Counter)
+{
+ /* Check the parameters */
+ assert_param(IS_WWDG_COUNTER(Counter));
+ WWDG->CR = WWDG_CR_WDGA | Counter;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup WWDG_Group3 Interrupts and flags management functions
+ * @brief Interrupts and flags management functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Interrupts and flags management functions #####
+ ==============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Checks whether the Early Wakeup interrupt flag is set or not.
+ * @param None
+ * @retval The new state of the Early Wakeup interrupt flag (SET or RESET).
+ */
+FlagStatus WWDG_GetFlagStatus(void)
+{
+ FlagStatus bitstatus = RESET;
+
+ if ((WWDG->SR) != (uint32_t)RESET)
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+ return bitstatus;
+}
+
+/**
+ * @brief Clears Early Wakeup interrupt flag.
+ * @param None
+ * @retval None
+ */
+void WWDG_ClearFlag(void)
+{
+ WWDG->SR = (uint32_t)RESET;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
diff --git a/bootloader_hk32f030m_uart_xmodem/hk32f030mf4p6.ld b/bootloader_hk32f030m_uart_xmodem/hk32f030mf4p6.ld
new file mode 100644
index 0000000..19b05cc
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/hk32f030mf4p6.ld
@@ -0,0 +1,155 @@
+/*
+******************************************************************************
+**
+** File : LinkerScript.ld
+**
+** Abstract : Linker script for HK32F030Mx series
+** Set heap size, stack size and stack location according
+** to application requirements.
+** Set memory bank area and size if external memory is used.
+**
+** Distribution: The file is distributed “as is,” without any warranty
+** of any kind.
+**
+*****************************************************************************
+*/
+
+/* Entry Point */
+ENTRY(Reset_Handler)
+
+/* Highest address of the user mode stack */
+_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of RAM */
+/*
+ Generate a link error if heap and stack don't fit into RAM.
+ These numbers affect the USED size of RAM
+*/
+_Min_Heap_Size = 0x00; /* required amount of heap: 0 bytes */
+_Min_Stack_Size = 0x800; /* required amount of stack: 2048 bytes */
+
+/* Specify the memory areas */
+MEMORY
+{
+ RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 4K
+ FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 16K
+}
+
+/* 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 */
+ *(.ramfunc*)
+ . = 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) }
+}
+
+