diff --git a/README.md b/README.md
index 3e8d753..2ff245f 100644
--- a/README.md
+++ b/README.md
@@ -16,4 +16,35 @@ Projects
[RS-485 USB HID KVM](RS485HID.md): USB Keyboard over RS-485
+File Layout
+-----------
+
+Note that things are a mess as they stand right now. The first project
+was based upon the SemTech reference code which implemented their own
+HAL on top of ST's HAL which is partly implemented on top of ARM's HAL,
+and in some cases bypasses them. It was also originally written not
+expecting to be used for another board.
+
+loramac/ - SemTech reference code. Has reference code for LoRa and the
+ Node151 based board.
+mk/ - Files supporting the build infrastructure.
+rs485hid/ - Files relating to the RS-485 HID project
+stm32/ - This is the HAL for ST based parts. It comtains the ARM CMSIS
+ HAL as well, for the parts the ST chose to use.
+strobe/ - Crypto code that form the basis of the protocol.
+
+Options
+-------
+
+Default on:
+STROBE - This contains all the cryptography parts.
+SYSINIT - This contains the initalization frmae work, similar to FreeBSD.
+
+Default off:
+NODE151 - Code necessary for the Heltech Node151 module.
+RS485FRAME - Code implementing framing tx/rx over RS-485.
+STM32F103 - Code for a STM32F103 based board.
+SX1276 - Code necessary for the LoRa Radio.
+USB_CDC - Code for implementing a USB CDC Endpoint.
+
diff --git a/RS485HID.md b/RS485HID.md
index 6011e4d..38b2b3a 100644
--- a/RS485HID.md
+++ b/RS485HID.md
@@ -22,6 +22,9 @@ These are the device that are under conideration for the project:
Currently looking at USART3, B0 for DE, B1 for RE.
+TIM2_CH4 can be mapped to PB11 (UART3 RX). This is to do break detection.
+Table 45 says TIM2_REMAP, either full or partial (value 1x).
+
Table 5 pin definitions of stm32f103c8.pdf
(all can be remapped)
diff --git a/mk/boards.mk b/mk/boards.mk
index 2fb4802..0e3fcbc 100644
--- a/mk/boards.mk
+++ b/mk/boards.mk
@@ -52,15 +52,19 @@ ARMTARGET?= -mcpu=cortex-m3 -mthumb
LINKER_SCRIPT=$(STM32)/f103c8t6/STM32F103C8T6_FLASH.ld
SRCS+= \
+ misc.c \
hal_generic.c \
startup_stm32f103xb.s \
stm32f1xx_hal.c \
stm32f1xx_hal_cortex.c \
+ stm32f1xx_hal_dma.c \
stm32f1xx_hal_gpio.c \
stm32f1xx_hal_pcd.c \
stm32f1xx_hal_pcd_ex.c \
+ stm32f1xx_hal_pwr.c \
stm32f1xx_hal_rcc.c \
stm32f1xx_hal_rcc_ex.c \
+ stm32f1xx_hal_uart.c \
stm32f1xx_ll_usb.c \
system_stm32f1xx.c
@@ -108,6 +112,14 @@ CFLAGS+= -I$(STM32)/l151ccux
CFLAGS+= -DSTM32L151xC
.endif
+# RS485 Framing
+.if ${MK_RS485FRAME} == "yes"
+SRCS+= \
+ rs485frame.c
+
+CFLAGS+= -I$(SRCTOP)/rs485hid
+.endif
+
# USB CDC
.if ${MK_USB_CDC} == "yes"
.PATH: $(STM32)/usb
diff --git a/mk/mu.opts.mk b/mk/mu.opts.mk
index 3725966..aeaf436 100644
--- a/mk/mu.opts.mk
+++ b/mk/mu.opts.mk
@@ -8,6 +8,7 @@ __DEFAULT_YES_OPTIONS = STROBE \
__DEFAULT_NO_OPTIONS = \
NODE151 \
+ RS485FRAME \
STM32F103 \
SX1276 \
USB_CDC
diff --git a/mk/mu.progs.mk b/mk/mu.progs.mk
index 26e3d8d..b80adbf 100644
--- a/mk/mu.progs.mk
+++ b/mk/mu.progs.mk
@@ -1,3 +1,31 @@
+# Copyright 2022 John-Mark Gurney.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (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 $(.OBJDIR) == $(.CURDIR)
+.error Need to set MAKEOBJDIR.
+.endif
+
.MAIN: all
.PHONY: all
diff --git a/rs485hid/Makefile b/rs485hid/Makefile
index 201f7f4..5852219 100644
--- a/rs485hid/Makefile
+++ b/rs485hid/Makefile
@@ -34,6 +34,7 @@ CFLAGS += -I$(.CURDIR)/..
WITH_STM32F103 = yes
WITH_USB_CDC = yes
+WITH_RS485FRAME = yes
.include <../mk/boards.mk>
diff --git a/rs485hid/rs485frame.c b/rs485hid/rs485frame.c
new file mode 100644
index 0000000..d3745cf
--- /dev/null
+++ b/rs485hid/rs485frame.c
@@ -0,0 +1,243 @@
+/*
+ * Code to TX/RX RS-485 frames.
+ *
+ */
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+const char *rs485err = NULL;
+
+static uint8_t rxbuf[1024];
+static txdone_fn_t txdone;
+static rxdone_fn_t rxdone;
+static txdone_fn_t errcb;
+
+static int doingrx = 0;
+static int doingtx = 0;
+
+static UART_HandleTypeDef rs485uart;
+
+/*
+ * Notes:
+ HAL_UARTEx_RxEventCallback rx evnts
+ * HAL_UART_TxCpltCallback tx_it completed
+ * HAL_UART_RxCpltCallback rx_it completed
+ * HAL_UART_ErrorCallback for errors
+ */
+
+void
+USART3_IRQHandler(void)
+{
+
+ HAL_UART_IRQHandler(&rs485uart);
+}
+
+void
+rs485_register(txdone_fn_t txf, rxdone_fn_t rxf, txdone_fn_t errf)
+{
+
+ txdone = txf;
+ rxdone = rxf;
+ errcb = errf;
+}
+
+static void
+settx(bool tx)
+{
+ GPIO_PinState s;
+
+ if (tx)
+ s = GPIO_PIN_SET;
+ else
+ s = GPIO_PIN_RESET;
+
+ HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, s);
+ HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, s);
+ HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, s);
+}
+
+void
+rs485_starttx(uint8_t *pkt, size_t len)
+{
+
+ /* XXX - make sure not tx'ing */
+ /* XXX - make sure line is idle */
+ if (doingrx) {
+ HAL_UART_AbortReceive_IT(&rs485uart);
+ }
+
+ settx(true);
+
+ HAL_UART_Transmit_IT(&rs485uart, pkt, len);
+}
+
+void
+HAL_UART_ErrorCallback(UART_HandleTypeDef *phuart)
+{
+
+ settx(false);
+ doingtx = 0;
+ doingrx = 0;
+ errcb();
+}
+
+void
+HAL_UART_TxCpltCallback(UART_HandleTypeDef *phuart)
+{
+
+ if (phuart != &rs485uart || txdone == NULL)
+ return;
+
+ settx(false);
+ doingtx = 0;
+
+ txdone();
+}
+
+void
+HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
+{
+ if (huart != &rs485uart || rxdone == NULL)
+ return;
+
+ doingrx = 0;
+
+ rxdone(rxbuf, Size);
+}
+
+/*
+ * Called when the buffer has been completed, i.e. it likely
+ * overflowed.
+ */
+void
+HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
+{
+
+ if (huart != &rs485uart || rxdone == NULL)
+ return;
+
+ doingrx = 0;
+ rxdone(NULL, 0);
+}
+
+/* USE_HAL_UART_REGISTER_CALLBACKS defaults to 0, so use this */
+void
+HAL_UART_MspInit(UART_HandleTypeDef *huart)
+{
+ GPIO_InitTypeDef GPIO_InitStruct;
+
+ /* UM1850 § 38.1.2 Page 550 */
+
+ /* 2.a */
+ __HAL_RCC_USART3_FORCE_RESET( );
+ __HAL_RCC_USART3_RELEASE_RESET( );
+ __HAL_RCC_USART3_CLK_ENABLE();
+
+ /* 2.b */
+ __HAL_RCC_GPIOB_CLK_ENABLE();
+ /* TX pin */
+ GPIO_InitStruct = (GPIO_InitTypeDef){
+ .Pin = GPIO_PIN_10,
+ .Mode = GPIO_MODE_AF_PP,
+ .Pull = GPIO_NOPULL,
+ .Speed = GPIO_SPEED_FREQ_LOW,
+ };
+ HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+ /* RX pin */
+ GPIO_InitStruct = (GPIO_InitTypeDef){
+ .Pin = GPIO_PIN_11,
+ .Mode = GPIO_MODE_AF_INPUT,
+ .Pull = GPIO_NOPULL,
+ .Speed = GPIO_SPEED_FREQ_LOW,
+ };
+ HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+
+ /* 2.c */
+ HAL_NVIC_SetPriority(USART3_IRQn, 1, 0);
+ HAL_NVIC_EnableIRQ(USART3_IRQn);
+
+ /* 2.d */
+ /* DMA unused */
+}
+
+const char *
+statustostr(HAL_StatusTypeDef r)
+{
+
+ switch (r) {
+ case HAL_OK:
+ return "ok";
+ case HAL_ERROR:
+ return "error";
+ case HAL_BUSY:
+ return "busy";
+ default:
+ return "unknown";
+ }
+}
+
+int
+rs485_startrx()
+{
+ HAL_StatusTypeDef r;
+
+ if (doingtx) {
+ rs485err = "doingtx";
+ return 0;
+ }
+
+ r = HAL_UARTEx_ReceiveToIdle_IT(&rs485uart, rxbuf, sizeof rxbuf);
+ if (r == HAL_BUSY) {
+ HAL_UART_AbortReceive_IT(&rs485uart);
+ r = HAL_UARTEx_ReceiveToIdle_IT(&rs485uart, rxbuf, sizeof rxbuf);
+ }
+
+ rs485err = statustostr(r);
+
+ return r == HAL_OK;
+}
+
+static void
+rs485frame_init(const void *v)
+{
+ GPIO_InitTypeDef GPIO_InitStruct;
+
+ /* setup DE/RE */
+ GPIO_InitStruct = (GPIO_InitTypeDef){
+ .Pin = GPIO_PIN_0|GPIO_PIN_1,
+ .Mode = GPIO_MODE_OUTPUT_OD,
+ .Pull = GPIO_NOPULL,
+ .Speed = GPIO_SPEED_FREQ_LOW, /* 2 MHz */
+ };
+ HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+
+ /* switch to RX */
+ settx(false);
+
+ /* UM1850 § 38.1.2 Page 550 */
+ /* 3 */
+ rs485uart = (UART_HandleTypeDef){
+ .Init.BaudRate = 230400,
+ .Init.WordLength = UART_WORDLENGTH_8B,
+ .Init.StopBits = UART_STOPBITS_1,
+ .Init.Parity = UART_PARITY_NONE,
+ .Init.HwFlowCtl = UART_HWCONTROL_NONE,
+ .Init.Mode = UART_MODE_TX_RX,
+ .Instance = USART3,
+ };
+
+ /* 4 */
+ HAL_UART_Init(&rs485uart);
+}
+SYSINIT(rs485frame_init, SI_SUB_STANDARD, SI_ORDER_FIRST, rs485frame_init, NULL);
diff --git a/rs485hid/rs485frame.h b/rs485hid/rs485frame.h
new file mode 100644
index 0000000..fb52dfb
--- /dev/null
+++ b/rs485hid/rs485frame.h
@@ -0,0 +1,35 @@
+/*-
+ * Copyright 2022 John-Mark Gurney.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+extern const char *rs485err;
+
+typedef void (*txdone_fn_t)(void);
+typedef void (*rxdone_fn_t)(const uint8_t *pkt, size_t len);
+
+void rs485_register(txdone_fn_t, rxdone_fn_t, txdone_fn_t errcb);
+
+void rs485_starttx(uint8_t *pkt, size_t len);
+int rs485_startrx();
diff --git a/rs485hid/rs485gw.c b/rs485hid/rs485gw.c
index 985b235..ea8cae9 100644
--- a/rs485hid/rs485gw.c
+++ b/rs485hid/rs485gw.c
@@ -26,6 +26,8 @@
#include
+#include
+
#include
#include
@@ -36,6 +38,14 @@
SYSINIT(hal_init, SI_SUB_HAL, SI_ORDER_FIRST, (void (*)(const void *))HAL_Init, NULL);
+static int dorx = 0;
+static uint8_t rxbuf[128];
+static int gotrxdone = 0;
+static int gottxdone = 0;
+static int goterr = 0;
+static int rxbufsize = 0;
+static int rxbuftrunc = 0;
+
static void
c13led(const void *none)
{
@@ -56,6 +66,11 @@ c13led(const void *none)
}
SYSINIT(c13led, SI_SUB_HAL, SI_ORDER_SECOND, c13led, NULL);
+#if 0
+#undef usb_printf
+#define usb_printf debug_printf
+#endif
+
/*
* Referenced from:
* Projects/STM32F103RB-Nucleo/Applications/USB_Device/HID_Standalone/Src/main.c
@@ -128,24 +143,28 @@ void
txdone(void)
{
- usb_printf("txdone\r\n");
- //Radio.Rx(0);
+ gottxdone = 1;
}
void
-txtimeout(void)
+errfunc(void)
{
- usb_printf("txtimeout\r\n");
+ goterr = 1;
}
void
-rxdone(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr)
+rxdone(const uint8_t *payload, size_t size)
{
- usb_printf("rxdone: size: %hu, rssi: %hd, snr: %d\r\ndata: ", size, rssi, snr);
- hexdump(payload, size);
- usb_printf("\r\n");
+ if (size > sizeof rxbuf) {
+ size = sizeof rxbuf;
+ rxbuftrunc = 1;
+ }
+
+ memcpy(rxbuf, payload, size);
+ rxbufsize = size;
+ gotrxdone = 1;
}
void
@@ -235,20 +254,29 @@ process_line(char *start, char *end)
usb_printf("invalid pkt\r\n");
return;
}
- //Radio.Send(pktbuf, len / 2);
+ rs485_starttx(pktbuf, len / 2);
return;
}
usb_printf("line: %.*s", end - start, start);
fflush(vcp_usb);
}
+static void
+WaitForIRQ()
+{
+
+ __disable_irq();
+ HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
+ __enable_irq( );
+}
+
int
main(void)
{
sysinit_run();
- //debug_printf("starting...\n");
+ debug_printf("starting...\n");
#if 1
int i;
@@ -281,8 +309,66 @@ main(void)
int inpbufpos = 0;
int cpylen;
+ rs485_register(txdone, rxdone, errfunc);
+
+ rs485_startrx();
+
+ unsigned lasttick = -1;
+ uint32_t gt;
loop:
- //BoardLowPowerHandler();
+ /*
+ * This is disabled as when it's enabled, it causes a hang
+ * when sending USB data. The USB CDC end point never becomes
+ * unbusy to allow the next send to progress.
+ */
+#if 0
+ /*
+ * A ms delay isn't a big deal, so no special locking is
+ * used to make sure we don't got to sleep w/ data pending.
+ */
+ WaitForIRQ();
+#else
+ (void)WaitForIRQ;
+#endif
+
+ gt = HAL_GetTick();
+ if (lasttick != gt / 1000) {
+ lasttick = gt / 1000;
+ //usb_printf("tick: %u\r\n", lasttick);
+ }
+
+ if (goterr) {
+ //usb_printf("error\r\n");
+ goterr = 0;
+ dorx = 1;
+ }
+
+ if (gottxdone) {
+ usb_printf("txdone\r\n");
+
+ dorx = 1;
+ gottxdone = 0;
+ }
+
+ if (gotrxdone) {
+ if (rxbuftrunc) {
+ rxbuftrunc = 0;
+ //usb_printf("rxdone: buffer overflow\r\n");
+ } else {
+ usb_printf("rxdone: size: %u\r\ndata: ", rxbufsize);
+ hexdump(rxbuf, rxbufsize);
+ usb_printf("\r\n");
+ }
+ dorx = 1;
+ gotrxdone = 0;
+ }
+
+ if (dorx) {
+ //usb_printf("dorx\r\n");
+ rs485_startrx();
+ //usb_printf("startrx res: %s\r\n", rs485err);
+ dorx = 0;
+ }
/* while we have data */
while (CDC_RX_LEN) {
diff --git a/si_usb.c b/si_usb.c
index 9d24ea2..4e662d6 100644
--- a/si_usb.c
+++ b/si_usb.c
@@ -4,11 +4,34 @@
#include
+#include
+#include
+
#include
static void
usb_cdc_init(const void *foo)
{
+ /*
+ * pretend that the device was newly plugged in
+ * see: https://stackoverflow.com/a/67336535
+ */
+
+ GPIO_InitTypeDef GPIO_InitStructure;
+
+ GPIO_InitStructure = (GPIO_InitTypeDef){
+ .Pin = GPIO_PIN_11|GPIO_PIN_12,
+ .Mode = GPIO_MODE_OUTPUT_PP,
+ .Pull = GPIO_PULLDOWN,
+ .Speed = GPIO_SPEED_HIGH,
+ };
+
+ __HAL_RCC_GPIOA_CLK_ENABLE();
+ HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
+ //HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, GPIO_PIN_RESET);
+ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_RESET);
+
+ HAL_Delay(10);
MX_USB_DEVICE_Init();
}
diff --git a/stm32/.srcs b/stm32/.srcs
index 5d3c192..f1d2142 100644
--- a/stm32/.srcs
+++ b/stm32/.srcs
@@ -14,12 +14,14 @@ f103c8t6/stm32f1xx_hal_adc.h STM32CubeF1 Drivers/STM32F1xx_HAL_Driver/Inc/stm32f
f103c8t6/stm32f1xx_hal_adc_ex.h STM32CubeF1 Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_adc_ex.h
f103c8t6/stm32f1xx_hal_cortex.h STM32CubeF1 Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cortex.h
f103c8t6/stm32f1xx_hal_def.h STM32CubeF1 Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h
+f103c8t6/stm32f1xx_hal_dma.c STM32CubeF1 Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c
f103c8t6/stm32f1xx_hal_dma.h STM32CubeF1 Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma.h
f103c8t6/stm32f1xx_hal_dma_ex.h STM32CubeF1 Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma_ex.h
f103c8t6/stm32f1xx_hal_flash.h STM32CubeF1 Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash.h
f103c8t6/stm32f1xx_hal_flash_ex.h STM32CubeF1 Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash_ex.h
f103c8t6/stm32f1xx_hal_gpio.h STM32CubeF1 Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio.h
f103c8t6/stm32f1xx_hal_gpio_ex.h STM32CubeF1 Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio_ex.h
+f103c8t6/stm32f1xx_hal_pwr.c STM32CubeF1 Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c
f103c8t6/stm32f1xx_hal_pwr.h STM32CubeF1 Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pwr.h
f103c8t6/stm32f1xx_hal_pcd.h STM32CubeF1 Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pcd.h
f103c8t6/stm32f1xx_hal_pcd_ex.h STM32CubeF1 Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pcd_ex.h
@@ -29,5 +31,6 @@ f103c8t6/stm32f1xx_hal_rcc_ex.c STM32CubeF1 Drivers/STM32F1xx_HAL_Driver/Src/stm
f103c8t6/stm32f1xx_hal_rcc_ex.h STM32CubeF1 Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc_ex.h
f103c8t6/stm32f1xx_hal_rtc.h STM32CubeF1 Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rtc.h
f103c8t6/stm32f1xx_hal_rtc_ex.h STM32CubeF1 Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rtc_ex.h
+f103c8t6/stm32f1xx_hal_uart.c STM32CubeF1 Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c
f103c8t6/stm32f1xx_hal_uart.h STM32CubeF1 Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_uart.h
f103c8t6/stm32f1xx_ll_usb.h STM32CubeF1 Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_usb.h
diff --git a/stm32/f103c8t6/main.h b/stm32/f103c8t6/main.h
index 91051c9..b3d10dd 100644
--- a/stm32/f103c8t6/main.h
+++ b/stm32/f103c8t6/main.h
@@ -3,4 +3,6 @@
#include "stm32f1xx_hal.h"
+void Error_Handler(void);
+
#endif /* _MAIN_H_ */
diff --git a/stm32/f103c8t6/stm32f1xx_hal_dma.c b/stm32/f103c8t6/stm32f1xx_hal_dma.c
new file mode 100644
index 0000000..62a1d28
--- /dev/null
+++ b/stm32/f103c8t6/stm32f1xx_hal_dma.c
@@ -0,0 +1,899 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_dma.c
+ * @author MCD Application Team
+ * @brief DMA HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the Direct Memory Access (DMA) peripheral:
+ * + Initialization and de-initialization functions
+ * + IO operation functions
+ * + Peripheral State and errors functions
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ (#) Enable and configure the peripheral to be connected to the DMA Channel
+ (except for internal SRAM / FLASH memories: no initialization is
+ necessary). Please refer to the Reference manual for connection between peripherals
+ and DMA requests.
+
+ (#) For a given Channel, program the required configuration through the following parameters:
+ Channel request, Transfer Direction, Source and Destination data formats,
+ Circular or Normal mode, Channel Priority level, Source and Destination Increment mode
+ using HAL_DMA_Init() function.
+
+ (#) Use HAL_DMA_GetState() function to return the DMA state and HAL_DMA_GetError() in case of error
+ detection.
+
+ (#) Use HAL_DMA_Abort() function to abort the current transfer
+
+ -@- In Memory-to-Memory transfer mode, Circular mode is not allowed.
+ *** Polling mode IO operation ***
+ =================================
+ [..]
+ (+) Use HAL_DMA_Start() to start DMA transfer after the configuration of Source
+ address and destination address and the Length of data to be transferred
+ (+) Use HAL_DMA_PollForTransfer() to poll for the end of current transfer, in this
+ case a fixed Timeout can be configured by User depending from his application.
+
+ *** Interrupt mode IO operation ***
+ ===================================
+ [..]
+ (+) Configure the DMA interrupt priority using HAL_NVIC_SetPriority()
+ (+) Enable the DMA IRQ handler using HAL_NVIC_EnableIRQ()
+ (+) Use HAL_DMA_Start_IT() to start DMA transfer after the configuration of
+ Source address and destination address and the Length of data to be transferred.
+ In this case the DMA interrupt is configured
+ (+) Use HAL_DMA_IRQHandler() called under DMA_IRQHandler() Interrupt subroutine
+ (+) At the end of data transfer HAL_DMA_IRQHandler() function is executed and user can
+ add his own function by customization of function pointer XferCpltCallback and
+ XferErrorCallback (i.e. a member of DMA handle structure).
+
+ *** DMA HAL driver macros list ***
+ =============================================
+ [..]
+ Below the list of most used macros in DMA HAL driver.
+
+ (+) __HAL_DMA_ENABLE: Enable the specified DMA Channel.
+ (+) __HAL_DMA_DISABLE: Disable the specified DMA Channel.
+ (+) __HAL_DMA_GET_FLAG: Get the DMA Channel pending flags.
+ (+) __HAL_DMA_CLEAR_FLAG: Clear the DMA Channel pending flags.
+ (+) __HAL_DMA_ENABLE_IT: Enable the specified DMA Channel interrupts.
+ (+) __HAL_DMA_DISABLE_IT: Disable the specified DMA Channel interrupts.
+ (+) __HAL_DMA_GET_IT_SOURCE: Check whether the specified DMA Channel interrupt has occurred or not.
+
+ [..]
+ (@) You can refer to the DMA HAL driver header file for more useful macros
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2016 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup DMA DMA
+ * @brief DMA HAL module driver
+ * @{
+ */
+
+#ifdef HAL_DMA_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/** @defgroup DMA_Private_Functions DMA Private Functions
+ * @{
+ */
+static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
+/**
+ * @}
+ */
+
+/* Exported functions ---------------------------------------------------------*/
+
+/** @defgroup DMA_Exported_Functions DMA Exported Functions
+ * @{
+ */
+
+/** @defgroup DMA_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and de-initialization functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Initialization and de-initialization functions #####
+ ===============================================================================
+ [..]
+ This section provides functions allowing to initialize the DMA Channel source
+ and destination addresses, incrementation and data sizes, transfer direction,
+ circular/normal mode selection, memory-to-memory mode selection and Channel priority value.
+ [..]
+ The HAL_DMA_Init() function follows the DMA configuration procedures as described in
+ reference manual.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initialize the DMA according to the specified
+ * parameters in the DMA_InitTypeDef and initialize the associated handle.
+ * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA Channel.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma)
+{
+ uint32_t tmp = 0U;
+
+ /* Check the DMA handle allocation */
+ if(hdma == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
+ assert_param(IS_DMA_DIRECTION(hdma->Init.Direction));
+ assert_param(IS_DMA_PERIPHERAL_INC_STATE(hdma->Init.PeriphInc));
+ assert_param(IS_DMA_MEMORY_INC_STATE(hdma->Init.MemInc));
+ assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(hdma->Init.PeriphDataAlignment));
+ assert_param(IS_DMA_MEMORY_DATA_SIZE(hdma->Init.MemDataAlignment));
+ assert_param(IS_DMA_MODE(hdma->Init.Mode));
+ assert_param(IS_DMA_PRIORITY(hdma->Init.Priority));
+
+#if defined (DMA2)
+ /* calculation of the channel index */
+ if ((uint32_t)(hdma->Instance) < (uint32_t)(DMA2_Channel1))
+ {
+ /* DMA1 */
+ hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2;
+ hdma->DmaBaseAddress = DMA1;
+ }
+ else
+ {
+ /* DMA2 */
+ hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA2_Channel1) / ((uint32_t)DMA2_Channel2 - (uint32_t)DMA2_Channel1)) << 2;
+ hdma->DmaBaseAddress = DMA2;
+ }
+#else
+ /* DMA1 */
+ hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2;
+ hdma->DmaBaseAddress = DMA1;
+#endif /* DMA2 */
+
+ /* Change DMA peripheral state */
+ hdma->State = HAL_DMA_STATE_BUSY;
+
+ /* Get the CR register value */
+ tmp = hdma->Instance->CCR;
+
+ /* Clear PL, MSIZE, PSIZE, MINC, PINC, CIRC and DIR bits */
+ tmp &= ((uint32_t)~(DMA_CCR_PL | DMA_CCR_MSIZE | DMA_CCR_PSIZE | \
+ DMA_CCR_MINC | DMA_CCR_PINC | DMA_CCR_CIRC | \
+ DMA_CCR_DIR));
+
+ /* Prepare the DMA Channel configuration */
+ tmp |= hdma->Init.Direction |
+ hdma->Init.PeriphInc | hdma->Init.MemInc |
+ hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment |
+ hdma->Init.Mode | hdma->Init.Priority;
+
+ /* Write to DMA Channel CR register */
+ hdma->Instance->CCR = tmp;
+
+ /* Initialise the error code */
+ hdma->ErrorCode = HAL_DMA_ERROR_NONE;
+
+ /* Initialize the DMA state*/
+ hdma->State = HAL_DMA_STATE_READY;
+ /* Allocate lock resource and initialize it */
+ hdma->Lock = HAL_UNLOCKED;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief DeInitialize the DMA peripheral.
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA Channel.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma)
+{
+ /* Check the DMA handle allocation */
+ if(hdma == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
+
+ /* Disable the selected DMA Channelx */
+ __HAL_DMA_DISABLE(hdma);
+
+ /* Reset DMA Channel control register */
+ hdma->Instance->CCR = 0U;
+
+ /* Reset DMA Channel Number of Data to Transfer register */
+ hdma->Instance->CNDTR = 0U;
+
+ /* Reset DMA Channel peripheral address register */
+ hdma->Instance->CPAR = 0U;
+
+ /* Reset DMA Channel memory address register */
+ hdma->Instance->CMAR = 0U;
+
+#if defined (DMA2)
+ /* calculation of the channel index */
+ if ((uint32_t)(hdma->Instance) < (uint32_t)(DMA2_Channel1))
+ {
+ /* DMA1 */
+ hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2;
+ hdma->DmaBaseAddress = DMA1;
+ }
+ else
+ {
+ /* DMA2 */
+ hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA2_Channel1) / ((uint32_t)DMA2_Channel2 - (uint32_t)DMA2_Channel1)) << 2;
+ hdma->DmaBaseAddress = DMA2;
+ }
+#else
+ /* DMA1 */
+ hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2;
+ hdma->DmaBaseAddress = DMA1;
+#endif /* DMA2 */
+
+ /* Clear all flags */
+ hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << (hdma->ChannelIndex));
+
+ /* Clean all callbacks */
+ hdma->XferCpltCallback = NULL;
+ hdma->XferHalfCpltCallback = NULL;
+ hdma->XferErrorCallback = NULL;
+ hdma->XferAbortCallback = NULL;
+
+ /* Reset the error code */
+ hdma->ErrorCode = HAL_DMA_ERROR_NONE;
+
+ /* Reset the DMA state */
+ hdma->State = HAL_DMA_STATE_RESET;
+
+ /* Release Lock */
+ __HAL_UNLOCK(hdma);
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup DMA_Exported_Functions_Group2 Input and Output operation functions
+ * @brief Input and Output operation functions
+ *
+@verbatim
+ ===============================================================================
+ ##### IO operation functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to:
+ (+) Configure the source, destination address and data length and Start DMA transfer
+ (+) Configure the source, destination address and data length and
+ Start DMA transfer with interrupt
+ (+) Abort DMA transfer
+ (+) Poll for transfer complete
+ (+) Handle DMA interrupt request
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Start the DMA Transfer.
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA Channel.
+ * @param SrcAddress: The source memory Buffer address
+ * @param DstAddress: The destination memory Buffer address
+ * @param DataLength: The length of data to be transferred from source to destination
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Check the parameters */
+ assert_param(IS_DMA_BUFFER_SIZE(DataLength));
+
+ /* Process locked */
+ __HAL_LOCK(hdma);
+
+ if(HAL_DMA_STATE_READY == hdma->State)
+ {
+ /* Change DMA peripheral state */
+ hdma->State = HAL_DMA_STATE_BUSY;
+ hdma->ErrorCode = HAL_DMA_ERROR_NONE;
+
+ /* Disable the peripheral */
+ __HAL_DMA_DISABLE(hdma);
+
+ /* Configure the source, destination address and the data length & clear flags*/
+ DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
+
+ /* Enable the Peripheral */
+ __HAL_DMA_ENABLE(hdma);
+ }
+ else
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdma);
+ status = HAL_BUSY;
+ }
+ return status;
+}
+
+/**
+ * @brief Start the DMA Transfer with interrupt enabled.
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA Channel.
+ * @param SrcAddress: The source memory Buffer address
+ * @param DstAddress: The destination memory Buffer address
+ * @param DataLength: The length of data to be transferred from source to destination
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Check the parameters */
+ assert_param(IS_DMA_BUFFER_SIZE(DataLength));
+
+ /* Process locked */
+ __HAL_LOCK(hdma);
+
+ if(HAL_DMA_STATE_READY == hdma->State)
+ {
+ /* Change DMA peripheral state */
+ hdma->State = HAL_DMA_STATE_BUSY;
+ hdma->ErrorCode = HAL_DMA_ERROR_NONE;
+
+ /* Disable the peripheral */
+ __HAL_DMA_DISABLE(hdma);
+
+ /* Configure the source, destination address and the data length & clear flags*/
+ DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
+
+ /* Enable the transfer complete interrupt */
+ /* Enable the transfer Error interrupt */
+ if(NULL != hdma->XferHalfCpltCallback)
+ {
+ /* Enable the Half transfer complete interrupt as well */
+ __HAL_DMA_ENABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
+ }
+ else
+ {
+ __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
+ __HAL_DMA_ENABLE_IT(hdma, (DMA_IT_TC | DMA_IT_TE));
+ }
+ /* Enable the Peripheral */
+ __HAL_DMA_ENABLE(hdma);
+ }
+ else
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdma);
+
+ /* Remain BUSY */
+ status = HAL_BUSY;
+ }
+ return status;
+}
+
+/**
+ * @brief Abort the DMA Transfer.
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA Channel.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ if(hdma->State != HAL_DMA_STATE_BUSY)
+ {
+ /* no transfer ongoing */
+ hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdma);
+
+ return HAL_ERROR;
+ }
+ else
+
+ {
+ /* Disable DMA IT */
+ __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
+
+ /* Disable the channel */
+ __HAL_DMA_DISABLE(hdma);
+
+ /* Clear all flags */
+ hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex);
+ }
+ /* Change the DMA state */
+ hdma->State = HAL_DMA_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdma);
+
+ return status;
+}
+
+/**
+ * @brief Aborts the DMA Transfer in Interrupt mode.
+ * @param hdma : pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA Channel.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ if(HAL_DMA_STATE_BUSY != hdma->State)
+ {
+ /* no transfer ongoing */
+ hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
+
+ status = HAL_ERROR;
+ }
+ else
+ {
+ /* Disable DMA IT */
+ __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
+
+ /* Disable the channel */
+ __HAL_DMA_DISABLE(hdma);
+
+ /* Clear all flags */
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_GI_FLAG_INDEX(hdma));
+
+ /* Change the DMA state */
+ hdma->State = HAL_DMA_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdma);
+
+ /* Call User Abort callback */
+ if(hdma->XferAbortCallback != NULL)
+ {
+ hdma->XferAbortCallback(hdma);
+ }
+ }
+ return status;
+}
+
+/**
+ * @brief Polling for transfer complete.
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA Channel.
+ * @param CompleteLevel: Specifies the DMA level complete.
+ * @param Timeout: Timeout duration.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout)
+{
+ uint32_t temp;
+ uint32_t tickstart = 0U;
+
+ if(HAL_DMA_STATE_BUSY != hdma->State)
+ {
+ /* no transfer ongoing */
+ hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
+ __HAL_UNLOCK(hdma);
+ return HAL_ERROR;
+ }
+
+ /* Polling mode not supported in circular mode */
+ if (RESET != (hdma->Instance->CCR & DMA_CCR_CIRC))
+ {
+ hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
+ return HAL_ERROR;
+ }
+
+ /* Get the level transfer complete flag */
+ if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
+ {
+ /* Transfer Complete flag */
+ temp = __HAL_DMA_GET_TC_FLAG_INDEX(hdma);
+ }
+ else
+ {
+ /* Half Transfer Complete flag */
+ temp = __HAL_DMA_GET_HT_FLAG_INDEX(hdma);
+ }
+
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ while(__HAL_DMA_GET_FLAG(hdma, temp) == RESET)
+ {
+ if((__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)) != RESET))
+ {
+ /* When a DMA transfer error occurs */
+ /* A hardware clear of its EN bits is performed */
+ /* Clear all flags */
+ hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex);
+
+ /* Update error code */
+ SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TE);
+
+ /* Change the DMA state */
+ hdma->State= HAL_DMA_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdma);
+
+ return HAL_ERROR;
+ }
+ /* Check for the Timeout */
+ if(Timeout != HAL_MAX_DELAY)
+ {
+ if((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
+ {
+ /* Update error code */
+ SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TIMEOUT);
+
+ /* Change the DMA state */
+ hdma->State = HAL_DMA_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdma);
+
+ return HAL_ERROR;
+ }
+ }
+ }
+
+ if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
+ {
+ /* Clear the transfer complete flag */
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
+
+ /* The selected Channelx EN bit is cleared (DMA is disabled and
+ all transfers are complete) */
+ hdma->State = HAL_DMA_STATE_READY;
+ }
+ else
+ {
+ /* Clear the half transfer complete flag */
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
+ }
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hdma);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Handles DMA interrupt request.
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA Channel.
+ * @retval None
+ */
+void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
+{
+ uint32_t flag_it = hdma->DmaBaseAddress->ISR;
+ uint32_t source_it = hdma->Instance->CCR;
+
+ /* Half Transfer Complete Interrupt management ******************************/
+ if (((flag_it & (DMA_FLAG_HT1 << hdma->ChannelIndex)) != RESET) && ((source_it & DMA_IT_HT) != RESET))
+ {
+ /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
+ if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
+ {
+ /* Disable the half transfer interrupt */
+ __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
+ }
+ /* Clear the half transfer complete flag */
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
+
+ /* DMA peripheral state is not updated in Half Transfer */
+ /* but in Transfer Complete case */
+
+ if(hdma->XferHalfCpltCallback != NULL)
+ {
+ /* Half transfer callback */
+ hdma->XferHalfCpltCallback(hdma);
+ }
+ }
+
+ /* Transfer Complete Interrupt management ***********************************/
+ else if (((flag_it & (DMA_FLAG_TC1 << hdma->ChannelIndex)) != RESET) && ((source_it & DMA_IT_TC) != RESET))
+ {
+ if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
+ {
+ /* Disable the transfer complete and error interrupt */
+ __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE | DMA_IT_TC);
+
+ /* Change the DMA state */
+ hdma->State = HAL_DMA_STATE_READY;
+ }
+ /* Clear the transfer complete flag */
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdma);
+
+ if(hdma->XferCpltCallback != NULL)
+ {
+ /* Transfer complete callback */
+ hdma->XferCpltCallback(hdma);
+ }
+ }
+
+ /* Transfer Error Interrupt management **************************************/
+ else if (( RESET != (flag_it & (DMA_FLAG_TE1 << hdma->ChannelIndex))) && (RESET != (source_it & DMA_IT_TE)))
+ {
+ /* When a DMA transfer error occurs */
+ /* A hardware clear of its EN bits is performed */
+ /* Disable ALL DMA IT */
+ __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
+
+ /* Clear all flags */
+ hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex);
+
+ /* Update error code */
+ hdma->ErrorCode = HAL_DMA_ERROR_TE;
+
+ /* Change the DMA state */
+ hdma->State = HAL_DMA_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdma);
+
+ if (hdma->XferErrorCallback != NULL)
+ {
+ /* Transfer error callback */
+ hdma->XferErrorCallback(hdma);
+ }
+ }
+ return;
+}
+
+/**
+ * @brief Register callbacks
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA Channel.
+ * @param CallbackID: User Callback identifer
+ * a HAL_DMA_CallbackIDTypeDef ENUM as parameter.
+ * @param pCallback: pointer to private callbacsk function which has pointer to
+ * a DMA_HandleTypeDef structure as parameter.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_DMA_RegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID, void (* pCallback)( DMA_HandleTypeDef * _hdma))
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Process locked */
+ __HAL_LOCK(hdma);
+
+ if(HAL_DMA_STATE_READY == hdma->State)
+ {
+ switch (CallbackID)
+ {
+ case HAL_DMA_XFER_CPLT_CB_ID:
+ hdma->XferCpltCallback = pCallback;
+ break;
+
+ case HAL_DMA_XFER_HALFCPLT_CB_ID:
+ hdma->XferHalfCpltCallback = pCallback;
+ break;
+
+ case HAL_DMA_XFER_ERROR_CB_ID:
+ hdma->XferErrorCallback = pCallback;
+ break;
+
+ case HAL_DMA_XFER_ABORT_CB_ID:
+ hdma->XferAbortCallback = pCallback;
+ break;
+
+ default:
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ status = HAL_ERROR;
+ }
+
+ /* Release Lock */
+ __HAL_UNLOCK(hdma);
+
+ return status;
+}
+
+/**
+ * @brief UnRegister callbacks
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA Channel.
+ * @param CallbackID: User Callback identifer
+ * a HAL_DMA_CallbackIDTypeDef ENUM as parameter.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Process locked */
+ __HAL_LOCK(hdma);
+
+ if(HAL_DMA_STATE_READY == hdma->State)
+ {
+ switch (CallbackID)
+ {
+ case HAL_DMA_XFER_CPLT_CB_ID:
+ hdma->XferCpltCallback = NULL;
+ break;
+
+ case HAL_DMA_XFER_HALFCPLT_CB_ID:
+ hdma->XferHalfCpltCallback = NULL;
+ break;
+
+ case HAL_DMA_XFER_ERROR_CB_ID:
+ hdma->XferErrorCallback = NULL;
+ break;
+
+ case HAL_DMA_XFER_ABORT_CB_ID:
+ hdma->XferAbortCallback = NULL;
+ break;
+
+ case HAL_DMA_XFER_ALL_CB_ID:
+ hdma->XferCpltCallback = NULL;
+ hdma->XferHalfCpltCallback = NULL;
+ hdma->XferErrorCallback = NULL;
+ hdma->XferAbortCallback = NULL;
+ break;
+
+ default:
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ status = HAL_ERROR;
+ }
+
+ /* Release Lock */
+ __HAL_UNLOCK(hdma);
+
+ return status;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup DMA_Exported_Functions_Group3 Peripheral State and Errors functions
+ * @brief Peripheral State and Errors functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral State and Errors functions #####
+ ===============================================================================
+ [..]
+ This subsection provides functions allowing to
+ (+) Check the DMA state
+ (+) Get error code
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Return the DMA hande state.
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA Channel.
+ * @retval HAL state
+ */
+HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma)
+{
+ /* Return DMA handle state */
+ return hdma->State;
+}
+
+/**
+ * @brief Return the DMA error code.
+ * @param hdma : pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA Channel.
+ * @retval DMA Error Code
+ */
+uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma)
+{
+ return hdma->ErrorCode;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup DMA_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Sets the DMA Transfer parameter.
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA Channel.
+ * @param SrcAddress: The source memory Buffer address
+ * @param DstAddress: The destination memory Buffer address
+ * @param DataLength: The length of data to be transferred from source to destination
+ * @retval HAL status
+ */
+static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
+{
+ /* Clear all flags */
+ hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex);
+
+ /* Configure DMA Channel data length */
+ hdma->Instance->CNDTR = DataLength;
+
+ /* Memory to Peripheral */
+ if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
+ {
+ /* Configure DMA Channel destination address */
+ hdma->Instance->CPAR = DstAddress;
+
+ /* Configure DMA Channel source address */
+ hdma->Instance->CMAR = SrcAddress;
+ }
+ /* Peripheral to Memory */
+ else
+ {
+ /* Configure DMA Channel source address */
+ hdma->Instance->CPAR = SrcAddress;
+
+ /* Configure DMA Channel destination address */
+ hdma->Instance->CMAR = DstAddress;
+ }
+}
+
+/**
+ * @}
+ */
+
+#endif /* HAL_DMA_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/stm32/f103c8t6/stm32f1xx_hal_pwr.c b/stm32/f103c8t6/stm32f1xx_hal_pwr.c
new file mode 100644
index 0000000..a9bf56b
--- /dev/null
+++ b/stm32/f103c8t6/stm32f1xx_hal_pwr.c
@@ -0,0 +1,621 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_pwr.c
+ * @author MCD Application Team
+ * @brief PWR HAL module driver.
+ *
+ * This file provides firmware functions to manage the following
+ * functionalities of the Power Controller (PWR) peripheral:
+ * + Initialization/de-initialization functions
+ * + Peripheral Control functions
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2016 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup PWR PWR
+ * @brief PWR HAL module driver
+ * @{
+ */
+
+#ifdef HAL_PWR_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+
+/** @defgroup PWR_Private_Constants PWR Private Constants
+ * @{
+ */
+
+/** @defgroup PWR_PVD_Mode_Mask PWR PVD Mode Mask
+ * @{
+ */
+#define PVD_MODE_IT 0x00010000U
+#define PVD_MODE_EVT 0x00020000U
+#define PVD_RISING_EDGE 0x00000001U
+#define PVD_FALLING_EDGE 0x00000002U
+/**
+ * @}
+ */
+
+
+/** @defgroup PWR_register_alias_address PWR Register alias address
+ * @{
+ */
+/* ------------- PWR registers bit address in the alias region ---------------*/
+#define PWR_OFFSET (PWR_BASE - PERIPH_BASE)
+#define PWR_CR_OFFSET 0x00U
+#define PWR_CSR_OFFSET 0x04U
+#define PWR_CR_OFFSET_BB (PWR_OFFSET + PWR_CR_OFFSET)
+#define PWR_CSR_OFFSET_BB (PWR_OFFSET + PWR_CSR_OFFSET)
+/**
+ * @}
+ */
+
+/** @defgroup PWR_CR_register_alias PWR CR Register alias address
+ * @{
+ */
+/* --- CR Register ---*/
+/* Alias word address of LPSDSR bit */
+#define LPSDSR_BIT_NUMBER PWR_CR_LPDS_Pos
+#define CR_LPSDSR_BB ((uint32_t)(PERIPH_BB_BASE + (PWR_CR_OFFSET_BB * 32U) + (LPSDSR_BIT_NUMBER * 4U)))
+
+/* Alias word address of DBP bit */
+#define DBP_BIT_NUMBER PWR_CR_DBP_Pos
+#define CR_DBP_BB ((uint32_t)(PERIPH_BB_BASE + (PWR_CR_OFFSET_BB * 32U) + (DBP_BIT_NUMBER * 4U)))
+
+/* Alias word address of PVDE bit */
+#define PVDE_BIT_NUMBER PWR_CR_PVDE_Pos
+#define CR_PVDE_BB ((uint32_t)(PERIPH_BB_BASE + (PWR_CR_OFFSET_BB * 32U) + (PVDE_BIT_NUMBER * 4U)))
+
+/**
+ * @}
+ */
+
+/** @defgroup PWR_CSR_register_alias PWR CSR Register alias address
+ * @{
+ */
+
+/* --- CSR Register ---*/
+/* Alias word address of EWUP1 bit */
+#define CSR_EWUP_BB(VAL) ((uint32_t)(PERIPH_BB_BASE + (PWR_CSR_OFFSET_BB * 32U) + (POSITION_VAL(VAL) * 4U)))
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/** @defgroup PWR_Private_Functions PWR Private Functions
+ * brief WFE cortex command overloaded for HAL_PWR_EnterSTOPMode usage only (see Workaround section)
+ * @{
+ */
+static void PWR_OverloadWfe(void);
+
+/* Private functions ---------------------------------------------------------*/
+__NOINLINE
+static void PWR_OverloadWfe(void)
+{
+ __asm volatile( "wfe" );
+ __asm volatile( "nop" );
+}
+
+/**
+ * @}
+ */
+
+
+/** @defgroup PWR_Exported_Functions PWR Exported Functions
+ * @{
+ */
+
+/** @defgroup PWR_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and de-initialization functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Initialization and de-initialization functions #####
+ ===============================================================================
+ [..]
+ After reset, the backup domain (RTC registers, RTC backup data
+ registers) is protected against possible unwanted
+ write accesses.
+ To enable access to the RTC Domain and RTC registers, proceed as follows:
+ (+) Enable the Power Controller (PWR) APB1 interface clock using the
+ __HAL_RCC_PWR_CLK_ENABLE() macro.
+ (+) Enable access to RTC domain using the HAL_PWR_EnableBkUpAccess() function.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Deinitializes the PWR peripheral registers to their default reset values.
+ * @retval None
+ */
+void HAL_PWR_DeInit(void)
+{
+ __HAL_RCC_PWR_FORCE_RESET();
+ __HAL_RCC_PWR_RELEASE_RESET();
+}
+
+/**
+ * @brief Enables access to the backup domain (RTC registers, RTC
+ * backup data registers ).
+ * @note If the HSE divided by 128 is used as the RTC clock, the
+ * Backup Domain Access should be kept enabled.
+ * @retval None
+ */
+void HAL_PWR_EnableBkUpAccess(void)
+{
+ /* Enable access to RTC and backup registers */
+ *(__IO uint32_t *) CR_DBP_BB = (uint32_t)ENABLE;
+}
+
+/**
+ * @brief Disables access to the backup domain (RTC registers, RTC
+ * backup data registers).
+ * @note If the HSE divided by 128 is used as the RTC clock, the
+ * Backup Domain Access should be kept enabled.
+ * @retval None
+ */
+void HAL_PWR_DisableBkUpAccess(void)
+{
+ /* Disable access to RTC and backup registers */
+ *(__IO uint32_t *) CR_DBP_BB = (uint32_t)DISABLE;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup PWR_Exported_Functions_Group2 Peripheral Control functions
+ * @brief Low Power modes configuration functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral Control functions #####
+ ===============================================================================
+
+ *** PVD configuration ***
+ =========================
+ [..]
+ (+) The PVD is used to monitor the VDD power supply by comparing it to a
+ threshold selected by the PVD Level (PLS[2:0] bits in the PWR_CR).
+
+ (+) A PVDO flag is available to indicate if VDD/VDDA is higher or lower
+ than the PVD threshold. This event is internally connected to the EXTI
+ line16 and can generate an interrupt if enabled. This is done through
+ __HAL_PVD_EXTI_ENABLE_IT() macro.
+ (+) The PVD is stopped in Standby mode.
+
+ *** WakeUp pin configuration ***
+ ================================
+ [..]
+ (+) WakeUp pin is used to wake up the system from Standby mode. This pin is
+ forced in input pull-down configuration and is active on rising edges.
+ (+) There is one WakeUp pin:
+ WakeUp Pin 1 on PA.00.
+
+ [..]
+
+ *** Low Power modes configuration ***
+ =====================================
+ [..]
+ The device features 3 low-power modes:
+ (+) Sleep mode: CPU clock off, all peripherals including Cortex-M3 core peripherals like
+ NVIC, SysTick, etc. are kept running
+ (+) Stop mode: All clocks are stopped
+ (+) Standby mode: 1.8V domain powered off
+
+
+ *** Sleep mode ***
+ ==================
+ [..]
+ (+) Entry:
+ The Sleep mode is entered by using the HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFx)
+ functions with
+ (++) PWR_SLEEPENTRY_WFI: enter SLEEP mode with WFI instruction
+ (++) PWR_SLEEPENTRY_WFE: enter SLEEP mode with WFE instruction
+
+ (+) Exit:
+ (++) WFI entry mode, Any peripheral interrupt acknowledged by the nested vectored interrupt
+ controller (NVIC) can wake up the device from Sleep mode.
+ (++) WFE entry mode, Any wakeup event can wake up the device from Sleep mode.
+ (+++) Any peripheral interrupt w/o NVIC configuration & SEVONPEND bit set in the Cortex (HAL_PWR_EnableSEVOnPend)
+ (+++) Any EXTI Line (Internal or External) configured in Event mode
+
+ *** Stop mode ***
+ =================
+ [..]
+ The Stop mode is based on the Cortex-M3 deepsleep mode combined with peripheral
+ clock gating. The voltage regulator can be configured either in normal or low-power mode.
+ In Stop mode, all clocks in the 1.8 V domain are stopped, the PLL, the HSI and the HSE RC
+ oscillators are disabled. SRAM and register contents are preserved.
+ In Stop mode, all I/O pins keep the same state as in Run mode.
+
+ (+) Entry:
+ The Stop mode is entered using the HAL_PWR_EnterSTOPMode(PWR_REGULATOR_VALUE, PWR_SLEEPENTRY_WFx )
+ function with:
+ (++) PWR_REGULATOR_VALUE= PWR_MAINREGULATOR_ON: Main regulator ON.
+ (++) PWR_REGULATOR_VALUE= PWR_LOWPOWERREGULATOR_ON: Low Power regulator ON.
+ (++) PWR_SLEEPENTRY_WFx= PWR_SLEEPENTRY_WFI: enter STOP mode with WFI instruction
+ (++) PWR_SLEEPENTRY_WFx= PWR_SLEEPENTRY_WFE: enter STOP mode with WFE instruction
+ (+) Exit:
+ (++) WFI entry mode, Any EXTI Line (Internal or External) configured in Interrupt mode with NVIC configured
+ (++) WFE entry mode, Any EXTI Line (Internal or External) configured in Event mode.
+
+ *** Standby mode ***
+ ====================
+ [..]
+ The Standby mode allows to achieve the lowest power consumption. It is based on the
+ Cortex-M3 deepsleep mode, with the voltage regulator disabled. The 1.8 V domain is
+ consequently powered off. The PLL, the HSI oscillator and the HSE oscillator are also
+ switched off. SRAM and register contents are lost except for registers in the Backup domain
+ and Standby circuitry
+
+ (+) Entry:
+ (++) The Standby mode is entered using the HAL_PWR_EnterSTANDBYMode() function.
+ (+) Exit:
+ (++) WKUP pin rising edge, RTC alarm event rising edge, external Reset in
+ NRSTpin, IWDG Reset
+
+ *** Auto-wakeup (AWU) from low-power mode ***
+ =============================================
+ [..]
+
+ (+) The MCU can be woken up from low-power mode by an RTC Alarm event,
+ without depending on an external interrupt (Auto-wakeup mode).
+
+ (+) RTC auto-wakeup (AWU) from the Stop and Standby modes
+
+ (++) To wake up from the Stop mode with an RTC alarm event, it is necessary to
+ configure the RTC to generate the RTC alarm using the HAL_RTC_SetAlarm_IT() function.
+
+ *** PWR Workarounds linked to Silicon Limitation ***
+ ====================================================
+ [..]
+ Below the list of all silicon limitations known on STM32F1xx prouct.
+
+ (#)Workarounds Implemented inside PWR HAL Driver
+ (##)Debugging Stop mode with WFE entry - overloaded the WFE by an internal function
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Configures the voltage threshold detected by the Power Voltage Detector(PVD).
+ * @param sConfigPVD: pointer to an PWR_PVDTypeDef structure that contains the configuration
+ * information for the PVD.
+ * @note Refer to the electrical characteristics of your device datasheet for
+ * more details about the voltage threshold corresponding to each
+ * detection level.
+ * @retval None
+ */
+void HAL_PWR_ConfigPVD(PWR_PVDTypeDef *sConfigPVD)
+{
+ /* Check the parameters */
+ assert_param(IS_PWR_PVD_LEVEL(sConfigPVD->PVDLevel));
+ assert_param(IS_PWR_PVD_MODE(sConfigPVD->Mode));
+
+ /* Set PLS[7:5] bits according to PVDLevel value */
+ MODIFY_REG(PWR->CR, PWR_CR_PLS, sConfigPVD->PVDLevel);
+
+ /* Clear any previous config. Keep it clear if no event or IT mode is selected */
+ __HAL_PWR_PVD_EXTI_DISABLE_EVENT();
+ __HAL_PWR_PVD_EXTI_DISABLE_IT();
+ __HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE();
+ __HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE();
+
+ /* Configure interrupt mode */
+ if((sConfigPVD->Mode & PVD_MODE_IT) == PVD_MODE_IT)
+ {
+ __HAL_PWR_PVD_EXTI_ENABLE_IT();
+ }
+
+ /* Configure event mode */
+ if((sConfigPVD->Mode & PVD_MODE_EVT) == PVD_MODE_EVT)
+ {
+ __HAL_PWR_PVD_EXTI_ENABLE_EVENT();
+ }
+
+ /* Configure the edge */
+ if((sConfigPVD->Mode & PVD_RISING_EDGE) == PVD_RISING_EDGE)
+ {
+ __HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE();
+ }
+
+ if((sConfigPVD->Mode & PVD_FALLING_EDGE) == PVD_FALLING_EDGE)
+ {
+ __HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE();
+ }
+}
+
+/**
+ * @brief Enables the Power Voltage Detector(PVD).
+ * @retval None
+ */
+void HAL_PWR_EnablePVD(void)
+{
+ /* Enable the power voltage detector */
+ *(__IO uint32_t *) CR_PVDE_BB = (uint32_t)ENABLE;
+}
+
+/**
+ * @brief Disables the Power Voltage Detector(PVD).
+ * @retval None
+ */
+void HAL_PWR_DisablePVD(void)
+{
+ /* Disable the power voltage detector */
+ *(__IO uint32_t *) CR_PVDE_BB = (uint32_t)DISABLE;
+}
+
+/**
+ * @brief Enables the WakeUp PINx functionality.
+ * @param WakeUpPinx: Specifies the Power Wake-Up pin to enable.
+ * This parameter can be one of the following values:
+ * @arg PWR_WAKEUP_PIN1
+ * @retval None
+ */
+void HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPinx)
+{
+ /* Check the parameter */
+ assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinx));
+ /* Enable the EWUPx pin */
+ *(__IO uint32_t *) CSR_EWUP_BB(WakeUpPinx) = (uint32_t)ENABLE;
+}
+
+/**
+ * @brief Disables the WakeUp PINx functionality.
+ * @param WakeUpPinx: Specifies the Power Wake-Up pin to disable.
+ * This parameter can be one of the following values:
+ * @arg PWR_WAKEUP_PIN1
+ * @retval None
+ */
+void HAL_PWR_DisableWakeUpPin(uint32_t WakeUpPinx)
+{
+ /* Check the parameter */
+ assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinx));
+ /* Disable the EWUPx pin */
+ *(__IO uint32_t *) CSR_EWUP_BB(WakeUpPinx) = (uint32_t)DISABLE;
+}
+
+/**
+ * @brief Enters Sleep mode.
+ * @note In Sleep mode, all I/O pins keep the same state as in Run mode.
+ * @param Regulator: Regulator state as no effect in SLEEP mode - allows to support portability from legacy software
+ * @param SLEEPEntry: Specifies if SLEEP mode is entered with WFI or WFE instruction.
+ * When WFI entry is used, tick interrupt have to be disabled if not desired as
+ * the interrupt wake up source.
+ * This parameter can be one of the following values:
+ * @arg PWR_SLEEPENTRY_WFI: enter SLEEP mode with WFI instruction
+ * @arg PWR_SLEEPENTRY_WFE: enter SLEEP mode with WFE instruction
+ * @retval None
+ */
+void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry)
+{
+ /* Check the parameters */
+ /* No check on Regulator because parameter not used in SLEEP mode */
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(Regulator);
+
+ assert_param(IS_PWR_SLEEP_ENTRY(SLEEPEntry));
+
+ /* Clear SLEEPDEEP bit of Cortex System Control Register */
+ CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
+
+ /* Select SLEEP mode entry -------------------------------------------------*/
+ if(SLEEPEntry == PWR_SLEEPENTRY_WFI)
+ {
+ /* Request Wait For Interrupt */
+ __WFI();
+ }
+ else
+ {
+ /* Request Wait For Event */
+ __SEV();
+ __WFE();
+ __WFE();
+ }
+}
+
+/**
+ * @brief Enters Stop mode.
+ * @note In Stop mode, all I/O pins keep the same state as in Run mode.
+ * @note When exiting Stop mode by using an interrupt or a wakeup event,
+ * HSI RC oscillator is selected as system clock.
+ * @note When the voltage regulator operates in low power mode, an additional
+ * startup delay is incurred when waking up from Stop mode.
+ * By keeping the internal regulator ON during Stop mode, the consumption
+ * is higher although the startup time is reduced.
+ * @param Regulator: Specifies the regulator state in Stop mode.
+ * This parameter can be one of the following values:
+ * @arg PWR_MAINREGULATOR_ON: Stop mode with regulator ON
+ * @arg PWR_LOWPOWERREGULATOR_ON: Stop mode with low power regulator ON
+ * @param STOPEntry: Specifies if Stop mode in entered with WFI or WFE instruction.
+ * This parameter can be one of the following values:
+ * @arg PWR_STOPENTRY_WFI: Enter Stop mode with WFI instruction
+ * @arg PWR_STOPENTRY_WFE: Enter Stop mode with WFE instruction
+ * @retval None
+ */
+void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry)
+{
+ /* Check the parameters */
+ assert_param(IS_PWR_REGULATOR(Regulator));
+ assert_param(IS_PWR_STOP_ENTRY(STOPEntry));
+
+ /* Clear PDDS bit in PWR register to specify entering in STOP mode when CPU enter in Deepsleep */
+ CLEAR_BIT(PWR->CR, PWR_CR_PDDS);
+
+ /* Select the voltage regulator mode by setting LPDS bit in PWR register according to Regulator parameter value */
+ MODIFY_REG(PWR->CR, PWR_CR_LPDS, Regulator);
+
+ /* Set SLEEPDEEP bit of Cortex System Control Register */
+ SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
+
+ /* Select Stop mode entry --------------------------------------------------*/
+ if(STOPEntry == PWR_STOPENTRY_WFI)
+ {
+ /* Request Wait For Interrupt */
+ __WFI();
+ }
+ else
+ {
+ /* Request Wait For Event */
+ __SEV();
+ PWR_OverloadWfe(); /* WFE redefine locally */
+ PWR_OverloadWfe(); /* WFE redefine locally */
+ }
+ /* Reset SLEEPDEEP bit of Cortex System Control Register */
+ CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
+}
+
+/**
+ * @brief Enters Standby mode.
+ * @note In Standby mode, all I/O pins are high impedance except for:
+ * - Reset pad (still available)
+ * - TAMPER pin if configured for tamper or calibration out.
+ * - WKUP pin (PA0) if enabled.
+ * @retval None
+ */
+void HAL_PWR_EnterSTANDBYMode(void)
+{
+ /* Select Standby mode */
+ SET_BIT(PWR->CR, PWR_CR_PDDS);
+
+ /* Set SLEEPDEEP bit of Cortex System Control Register */
+ SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
+
+ /* This option is used to ensure that store operations are completed */
+#if defined ( __CC_ARM)
+ __force_stores();
+#endif
+ /* Request Wait For Interrupt */
+ __WFI();
+}
+
+
+/**
+ * @brief Indicates Sleep-On-Exit when returning from Handler mode to Thread mode.
+ * @note Set SLEEPONEXIT bit of SCR register. When this bit is set, the processor
+ * re-enters SLEEP mode when an interruption handling is over.
+ * Setting this bit is useful when the processor is expected to run only on
+ * interruptions handling.
+ * @retval None
+ */
+void HAL_PWR_EnableSleepOnExit(void)
+{
+ /* Set SLEEPONEXIT bit of Cortex System Control Register */
+ SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPONEXIT_Msk));
+}
+
+
+/**
+ * @brief Disables Sleep-On-Exit feature when returning from Handler mode to Thread mode.
+ * @note Clears SLEEPONEXIT bit of SCR register. When this bit is set, the processor
+ * re-enters SLEEP mode when an interruption handling is over.
+ * @retval None
+ */
+void HAL_PWR_DisableSleepOnExit(void)
+{
+ /* Clear SLEEPONEXIT bit of Cortex System Control Register */
+ CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPONEXIT_Msk));
+}
+
+
+/**
+ * @brief Enables CORTEX M3 SEVONPEND bit.
+ * @note Sets SEVONPEND bit of SCR register. When this bit is set, this causes
+ * WFE to wake up when an interrupt moves from inactive to pended.
+ * @retval None
+ */
+void HAL_PWR_EnableSEVOnPend(void)
+{
+ /* Set SEVONPEND bit of Cortex System Control Register */
+ SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SEVONPEND_Msk));
+}
+
+
+/**
+ * @brief Disables CORTEX M3 SEVONPEND bit.
+ * @note Clears SEVONPEND bit of SCR register. When this bit is set, this causes
+ * WFE to wake up when an interrupt moves from inactive to pended.
+ * @retval None
+ */
+void HAL_PWR_DisableSEVOnPend(void)
+{
+ /* Clear SEVONPEND bit of Cortex System Control Register */
+ CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SEVONPEND_Msk));
+}
+
+
+
+/**
+ * @brief This function handles the PWR PVD interrupt request.
+ * @note This API should be called under the PVD_IRQHandler().
+ * @retval None
+ */
+void HAL_PWR_PVD_IRQHandler(void)
+{
+ /* Check PWR exti flag */
+ if(__HAL_PWR_PVD_EXTI_GET_FLAG() != RESET)
+ {
+ /* PWR PVD interrupt user callback */
+ HAL_PWR_PVDCallback();
+
+ /* Clear PWR Exti pending bit */
+ __HAL_PWR_PVD_EXTI_CLEAR_FLAG();
+ }
+}
+
+/**
+ * @brief PWR PVD interrupt callback
+ * @retval None
+ */
+__weak void HAL_PWR_PVDCallback(void)
+{
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_PWR_PVDCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* HAL_PWR_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/stm32/f103c8t6/stm32f1xx_hal_uart.c b/stm32/f103c8t6/stm32f1xx_hal_uart.c
new file mode 100644
index 0000000..e56360a
--- /dev/null
+++ b/stm32/f103c8t6/stm32f1xx_hal_uart.c
@@ -0,0 +1,3738 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_uart.c
+ * @author MCD Application Team
+ * @brief UART HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the Universal Asynchronous Receiver Transmitter Peripheral (UART).
+ * + Initialization and de-initialization functions
+ * + IO operation functions
+ * + Peripheral Control functions
+ * + Peripheral State and Errors functions
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ The UART HAL driver can be used as follows:
+
+ (#) Declare a UART_HandleTypeDef handle structure (eg. UART_HandleTypeDef huart).
+ (#) Initialize the UART low level resources by implementing the HAL_UART_MspInit() API:
+ (##) Enable the USARTx interface clock.
+ (##) UART pins configuration:
+ (+++) Enable the clock for the UART GPIOs.
+ (+++) Configure the UART TX/RX pins as alternate function pull-up.
+ (##) NVIC configuration if you need to use interrupt process (HAL_UART_Transmit_IT()
+ and HAL_UART_Receive_IT() APIs):
+ (+++) Configure the USARTx interrupt priority.
+ (+++) Enable the NVIC USART IRQ handle.
+ (##) DMA Configuration if you need to use DMA process (HAL_UART_Transmit_DMA()
+ and HAL_UART_Receive_DMA() APIs):
+ (+++) Declare a DMA handle structure for the Tx/Rx channel.
+ (+++) Enable the DMAx interface clock.
+ (+++) Configure the declared DMA handle structure with the required
+ Tx/Rx parameters.
+ (+++) Configure the DMA Tx/Rx channel.
+ (+++) Associate the initialized DMA handle to the UART DMA Tx/Rx handle.
+ (+++) Configure the priority and enable the NVIC for the transfer complete
+ interrupt on the DMA Tx/Rx channel.
+ (+++) Configure the USARTx interrupt priority and enable the NVIC USART IRQ handle
+ (used for last byte sending completion detection in DMA non circular mode)
+
+ (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware
+ flow control and Mode(Receiver/Transmitter) in the huart Init structure.
+
+ (#) For the UART asynchronous mode, initialize the UART registers by calling
+ the HAL_UART_Init() API.
+
+ (#) For the UART Half duplex mode, initialize the UART registers by calling
+ the HAL_HalfDuplex_Init() API.
+
+ (#) For the LIN mode, initialize the UART registers by calling the HAL_LIN_Init() API.
+
+ (#) For the Multi-Processor mode, initialize the UART registers by calling
+ the HAL_MultiProcessor_Init() API.
+
+ [..]
+ (@) The specific UART interrupts (Transmission complete interrupt,
+ RXNE interrupt and Error Interrupts) will be managed using the macros
+ __HAL_UART_ENABLE_IT() and __HAL_UART_DISABLE_IT() inside the transmit
+ and receive process.
+
+ [..]
+ (@) These APIs (HAL_UART_Init() and HAL_HalfDuplex_Init()) configure also the
+ low level Hardware GPIO, CLOCK, CORTEX...etc) by calling the customized
+ HAL_UART_MspInit() API.
+
+ ##### Callback registration #####
+ ==================================
+
+ [..]
+ The compilation define USE_HAL_UART_REGISTER_CALLBACKS when set to 1
+ allows the user to configure dynamically the driver callbacks.
+
+ [..]
+ Use Function @ref HAL_UART_RegisterCallback() to register a user callback.
+ Function @ref HAL_UART_RegisterCallback() allows to register following callbacks:
+ (+) TxHalfCpltCallback : Tx Half Complete Callback.
+ (+) TxCpltCallback : Tx Complete Callback.
+ (+) RxHalfCpltCallback : Rx Half Complete Callback.
+ (+) RxCpltCallback : Rx Complete Callback.
+ (+) ErrorCallback : Error Callback.
+ (+) AbortCpltCallback : Abort Complete Callback.
+ (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback.
+ (+) AbortReceiveCpltCallback : Abort Receive Complete Callback.
+ (+) MspInitCallback : UART MspInit.
+ (+) MspDeInitCallback : UART MspDeInit.
+ This function takes as parameters the HAL peripheral handle, the Callback ID
+ and a pointer to the user callback function.
+
+ [..]
+ Use function @ref HAL_UART_UnRegisterCallback() to reset a callback to the default
+ weak (surcharged) function.
+ @ref HAL_UART_UnRegisterCallback() takes as parameters the HAL peripheral handle,
+ and the Callback ID.
+ This function allows to reset following callbacks:
+ (+) TxHalfCpltCallback : Tx Half Complete Callback.
+ (+) TxCpltCallback : Tx Complete Callback.
+ (+) RxHalfCpltCallback : Rx Half Complete Callback.
+ (+) RxCpltCallback : Rx Complete Callback.
+ (+) ErrorCallback : Error Callback.
+ (+) AbortCpltCallback : Abort Complete Callback.
+ (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback.
+ (+) AbortReceiveCpltCallback : Abort Receive Complete Callback.
+ (+) MspInitCallback : UART MspInit.
+ (+) MspDeInitCallback : UART MspDeInit.
+
+ [..]
+ For specific callback RxEventCallback, use dedicated registration/reset functions:
+ respectively @ref HAL_UART_RegisterRxEventCallback() , @ref HAL_UART_UnRegisterRxEventCallback().
+
+ [..]
+ By default, after the @ref HAL_UART_Init() and when the state is HAL_UART_STATE_RESET
+ all callbacks are set to the corresponding weak (surcharged) functions:
+ examples @ref HAL_UART_TxCpltCallback(), @ref HAL_UART_RxHalfCpltCallback().
+ Exception done for MspInit and MspDeInit functions that are respectively
+ reset to the legacy weak (surcharged) functions in the @ref HAL_UART_Init()
+ and @ref HAL_UART_DeInit() only when these callbacks are null (not registered beforehand).
+ If not, MspInit or MspDeInit are not null, the @ref HAL_UART_Init() and @ref HAL_UART_DeInit()
+ keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
+
+ [..]
+ Callbacks can be registered/unregistered in HAL_UART_STATE_READY state only.
+ Exception done MspInit/MspDeInit that can be registered/unregistered
+ in HAL_UART_STATE_READY or HAL_UART_STATE_RESET state, thus registered (user)
+ MspInit/DeInit callbacks can be used during the Init/DeInit.
+ In that case first register the MspInit/MspDeInit user callbacks
+ using @ref HAL_UART_RegisterCallback() before calling @ref HAL_UART_DeInit()
+ or @ref HAL_UART_Init() function.
+
+ [..]
+ When The compilation define USE_HAL_UART_REGISTER_CALLBACKS is set to 0 or
+ not defined, the callback registration feature is not available
+ and weak (surcharged) callbacks are used.
+
+ [..]
+ Three operation modes are available within this driver :
+
+ *** Polling mode IO operation ***
+ =================================
+ [..]
+ (+) Send an amount of data in blocking mode using HAL_UART_Transmit()
+ (+) Receive an amount of data in blocking mode using HAL_UART_Receive()
+
+ *** Interrupt mode IO operation ***
+ ===================================
+ [..]
+ (+) Send an amount of data in non blocking mode using HAL_UART_Transmit_IT()
+ (+) At transmission end of transfer HAL_UART_TxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_UART_TxCpltCallback
+ (+) Receive an amount of data in non blocking mode using HAL_UART_Receive_IT()
+ (+) At reception end of transfer HAL_UART_RxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_UART_RxCpltCallback
+ (+) In case of transfer Error, HAL_UART_ErrorCallback() function is executed and user can
+ add his own code by customization of function pointer HAL_UART_ErrorCallback
+
+ *** DMA mode IO operation ***
+ ==============================
+ [..]
+ (+) Send an amount of data in non blocking mode (DMA) using HAL_UART_Transmit_DMA()
+ (+) At transmission end of half transfer HAL_UART_TxHalfCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_UART_TxHalfCpltCallback
+ (+) At transmission end of transfer HAL_UART_TxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_UART_TxCpltCallback
+ (+) Receive an amount of data in non blocking mode (DMA) using HAL_UART_Receive_DMA()
+ (+) At reception end of half transfer HAL_UART_RxHalfCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_UART_RxHalfCpltCallback
+ (+) At reception end of transfer HAL_UART_RxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_UART_RxCpltCallback
+ (+) In case of transfer Error, HAL_UART_ErrorCallback() function is executed and user can
+ add his own code by customization of function pointer HAL_UART_ErrorCallback
+ (+) Pause the DMA Transfer using HAL_UART_DMAPause()
+ (+) Resume the DMA Transfer using HAL_UART_DMAResume()
+ (+) Stop the DMA Transfer using HAL_UART_DMAStop()
+
+
+ [..] This subsection also provides a set of additional functions providing enhanced reception
+ services to user. (For example, these functions allow application to handle use cases
+ where number of data to be received is unknown).
+
+ (#) Compared to standard reception services which only consider number of received
+ data elements as reception completion criteria, these functions also consider additional events
+ as triggers for updating reception status to caller :
+ (+) Detection of inactivity period (RX line has not been active for a given period).
+ (++) RX inactivity detected by IDLE event, i.e. RX line has been in idle state (normally high state)
+ for 1 frame time, after last received byte.
+
+ (#) There are two mode of transfer:
+ (+) Blocking mode: The reception is performed in polling mode, until either expected number of data is received,
+ or till IDLE event occurs. Reception is handled only during function execution.
+ When function exits, no data reception could occur. HAL status and number of actually received data elements,
+ are returned by function after finishing transfer.
+ (+) Non-Blocking mode: The reception is performed using Interrupts or DMA.
+ These API's return the HAL status.
+ The end of the data processing will be indicated through the
+ dedicated UART IRQ when using Interrupt mode or the DMA IRQ when using DMA mode.
+ The HAL_UARTEx_RxEventCallback() user callback will be executed during Receive process
+ The HAL_UART_ErrorCallback()user callback will be executed when a reception error is detected.
+
+ (#) Blocking mode API:
+ (+) HAL_UARTEx_ReceiveToIdle()
+
+ (#) Non-Blocking mode API with Interrupt:
+ (+) HAL_UARTEx_ReceiveToIdle_IT()
+
+ (#) Non-Blocking mode API with DMA:
+ (+) HAL_UARTEx_ReceiveToIdle_DMA()
+
+
+ *** UART HAL driver macros list ***
+ =============================================
+ [..]
+ Below the list of most used macros in UART HAL driver.
+
+ (+) __HAL_UART_ENABLE: Enable the UART peripheral
+ (+) __HAL_UART_DISABLE: Disable the UART peripheral
+ (+) __HAL_UART_GET_FLAG : Check whether the specified UART flag is set or not
+ (+) __HAL_UART_CLEAR_FLAG : Clear the specified UART pending flag
+ (+) __HAL_UART_ENABLE_IT: Enable the specified UART interrupt
+ (+) __HAL_UART_DISABLE_IT: Disable the specified UART interrupt
+ (+) __HAL_UART_GET_IT_SOURCE: Check whether the specified UART interrupt has occurred or not
+
+ [..]
+ (@) You can refer to the UART HAL driver header file for more useful macros
+
+ @endverbatim
+ [..]
+ (@) Additional remark: If the parity is enabled, then the MSB bit of the data written
+ in the data register is transmitted but is changed by the parity bit.
+ Depending on the frame length defined by the M bit (8-bits or 9-bits),
+ the possible UART frame formats are as listed in the following table:
+ +-------------------------------------------------------------+
+ | M bit | PCE bit | UART frame |
+ |---------------------|---------------------------------------|
+ | 0 | 0 | | SB | 8 bit data | STB | |
+ |---------|-----------|---------------------------------------|
+ | 0 | 1 | | SB | 7 bit data | PB | STB | |
+ |---------|-----------|---------------------------------------|
+ | 1 | 0 | | SB | 9 bit data | STB | |
+ |---------|-----------|---------------------------------------|
+ | 1 | 1 | | SB | 8 bit data | PB | STB | |
+ +-------------------------------------------------------------+
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2016 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup UART UART
+ * @brief HAL UART module driver
+ * @{
+ */
+#ifdef HAL_UART_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @addtogroup UART_Private_Constants
+ * @{
+ */
+/**
+ * @}
+ */
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/** @addtogroup UART_Private_Functions UART Private Functions
+ * @{
+ */
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+void UART_InitCallbacksToDefault(UART_HandleTypeDef *huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+static void UART_EndTxTransfer(UART_HandleTypeDef *huart);
+static void UART_EndRxTransfer(UART_HandleTypeDef *huart);
+static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma);
+static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
+static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
+static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
+static void UART_DMAError(DMA_HandleTypeDef *hdma);
+static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma);
+static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
+static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
+static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
+static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
+static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart);
+static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart);
+static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart);
+static HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout);
+static void UART_SetConfig(UART_HandleTypeDef *huart);
+
+/**
+ * @}
+ */
+
+/* Exported functions ---------------------------------------------------------*/
+/** @defgroup UART_Exported_Functions UART Exported Functions
+ * @{
+ */
+
+/** @defgroup UART_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Initialization and Configuration functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to initialize the USARTx or the UARTy
+ in asynchronous mode.
+ (+) For the asynchronous mode only these parameters can be configured:
+ (++) Baud Rate
+ (++) Word Length
+ (++) Stop Bit
+ (++) Parity: If the parity is enabled, then the MSB bit of the data written
+ in the data register is transmitted but is changed by the parity bit.
+ Depending on the frame length defined by the M bit (8-bits or 9-bits),
+ please refer to Reference manual for possible UART frame formats.
+ (++) Hardware flow control
+ (++) Receiver/transmitter modes
+ (++) Over Sampling Method
+ [..]
+ The HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init() and HAL_MultiProcessor_Init() APIs
+ follow respectively the UART asynchronous, UART Half duplex, LIN and Multi-Processor configuration
+ procedures (details for the procedures are available in reference manuals
+ (RM0008 for STM32F10Xxx MCUs and RM0041 for STM32F100xx MCUs)).
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the UART mode according to the specified parameters in
+ * the UART_InitTypeDef and create the associated handle.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart)
+{
+ /* Check the UART handle allocation */
+ if (huart == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ if (huart->Init.HwFlowCtl != UART_HWCONTROL_NONE)
+ {
+ /* The hardware flow control is available only for USART1, USART2 and USART3 */
+ assert_param(IS_UART_HWFLOW_INSTANCE(huart->Instance));
+ assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl));
+ }
+ else
+ {
+ assert_param(IS_UART_INSTANCE(huart->Instance));
+ }
+ assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
+#if defined(USART_CR1_OVER8)
+ assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
+#endif /* USART_CR1_OVER8 */
+
+ if (huart->gState == HAL_UART_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ huart->Lock = HAL_UNLOCKED;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ UART_InitCallbacksToDefault(huart);
+
+ if (huart->MspInitCallback == NULL)
+ {
+ huart->MspInitCallback = HAL_UART_MspInit;
+ }
+
+ /* Init the low level hardware */
+ huart->MspInitCallback(huart);
+#else
+ /* Init the low level hardware : GPIO, CLOCK */
+ HAL_UART_MspInit(huart);
+#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
+ }
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /* Disable the peripheral */
+ __HAL_UART_DISABLE(huart);
+
+ /* Set the UART Communication parameters */
+ UART_SetConfig(huart);
+
+ /* In asynchronous mode, the following bits must be kept cleared:
+ - LINEN and CLKEN bits in the USART_CR2 register,
+ - SCEN, HDSEL and IREN bits in the USART_CR3 register.*/
+ CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
+ CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
+
+ /* Enable the peripheral */
+ __HAL_UART_ENABLE(huart);
+
+ /* Initialize the UART state */
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->gState = HAL_UART_STATE_READY;
+ huart->RxState = HAL_UART_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the half-duplex mode according to the specified
+ * parameters in the UART_InitTypeDef and create the associated handle.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart)
+{
+ /* Check the UART handle allocation */
+ if (huart == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_UART_HALFDUPLEX_INSTANCE(huart->Instance));
+ assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
+#if defined(USART_CR1_OVER8)
+ assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
+#endif /* USART_CR1_OVER8 */
+
+ if (huart->gState == HAL_UART_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ huart->Lock = HAL_UNLOCKED;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ UART_InitCallbacksToDefault(huart);
+
+ if (huart->MspInitCallback == NULL)
+ {
+ huart->MspInitCallback = HAL_UART_MspInit;
+ }
+
+ /* Init the low level hardware */
+ huart->MspInitCallback(huart);
+#else
+ /* Init the low level hardware : GPIO, CLOCK */
+ HAL_UART_MspInit(huart);
+#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
+ }
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /* Disable the peripheral */
+ __HAL_UART_DISABLE(huart);
+
+ /* Set the UART Communication parameters */
+ UART_SetConfig(huart);
+
+ /* In half-duplex mode, the following bits must be kept cleared:
+ - LINEN and CLKEN bits in the USART_CR2 register,
+ - SCEN and IREN bits in the USART_CR3 register.*/
+ CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
+ CLEAR_BIT(huart->Instance->CR3, (USART_CR3_IREN | USART_CR3_SCEN));
+
+ /* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */
+ SET_BIT(huart->Instance->CR3, USART_CR3_HDSEL);
+
+ /* Enable the peripheral */
+ __HAL_UART_ENABLE(huart);
+
+ /* Initialize the UART state*/
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->gState = HAL_UART_STATE_READY;
+ huart->RxState = HAL_UART_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the LIN mode according to the specified
+ * parameters in the UART_InitTypeDef and create the associated handle.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param BreakDetectLength Specifies the LIN break detection length.
+ * This parameter can be one of the following values:
+ * @arg UART_LINBREAKDETECTLENGTH_10B: 10-bit break detection
+ * @arg UART_LINBREAKDETECTLENGTH_11B: 11-bit break detection
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLength)
+{
+ /* Check the UART handle allocation */
+ if (huart == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the LIN UART instance */
+ assert_param(IS_UART_LIN_INSTANCE(huart->Instance));
+
+ /* Check the Break detection length parameter */
+ assert_param(IS_UART_LIN_BREAK_DETECT_LENGTH(BreakDetectLength));
+ assert_param(IS_UART_LIN_WORD_LENGTH(huart->Init.WordLength));
+#if defined(USART_CR1_OVER8)
+ assert_param(IS_UART_LIN_OVERSAMPLING(huart->Init.OverSampling));
+#endif /* USART_CR1_OVER8 */
+
+ if (huart->gState == HAL_UART_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ huart->Lock = HAL_UNLOCKED;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ UART_InitCallbacksToDefault(huart);
+
+ if (huart->MspInitCallback == NULL)
+ {
+ huart->MspInitCallback = HAL_UART_MspInit;
+ }
+
+ /* Init the low level hardware */
+ huart->MspInitCallback(huart);
+#else
+ /* Init the low level hardware : GPIO, CLOCK */
+ HAL_UART_MspInit(huart);
+#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
+ }
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /* Disable the peripheral */
+ __HAL_UART_DISABLE(huart);
+
+ /* Set the UART Communication parameters */
+ UART_SetConfig(huart);
+
+ /* In LIN mode, the following bits must be kept cleared:
+ - CLKEN bits in the USART_CR2 register,
+ - SCEN, HDSEL and IREN bits in the USART_CR3 register.*/
+ CLEAR_BIT(huart->Instance->CR2, (USART_CR2_CLKEN));
+ CLEAR_BIT(huart->Instance->CR3, (USART_CR3_HDSEL | USART_CR3_IREN | USART_CR3_SCEN));
+
+ /* Enable the LIN mode by setting the LINEN bit in the CR2 register */
+ SET_BIT(huart->Instance->CR2, USART_CR2_LINEN);
+
+ /* Set the USART LIN Break detection length. */
+ CLEAR_BIT(huart->Instance->CR2, USART_CR2_LBDL);
+ SET_BIT(huart->Instance->CR2, BreakDetectLength);
+
+ /* Enable the peripheral */
+ __HAL_UART_ENABLE(huart);
+
+ /* Initialize the UART state*/
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->gState = HAL_UART_STATE_READY;
+ huart->RxState = HAL_UART_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the Multi-Processor mode according to the specified
+ * parameters in the UART_InitTypeDef and create the associated handle.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param Address USART address
+ * @param WakeUpMethod specifies the USART wake-up method.
+ * This parameter can be one of the following values:
+ * @arg UART_WAKEUPMETHOD_IDLELINE: Wake-up by an idle line detection
+ * @arg UART_WAKEUPMETHOD_ADDRESSMARK: Wake-up by an address mark
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Address, uint32_t WakeUpMethod)
+{
+ /* Check the UART handle allocation */
+ if (huart == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_UART_INSTANCE(huart->Instance));
+
+ /* Check the Address & wake up method parameters */
+ assert_param(IS_UART_WAKEUPMETHOD(WakeUpMethod));
+ assert_param(IS_UART_ADDRESS(Address));
+ assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
+#if defined(USART_CR1_OVER8)
+ assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
+#endif /* USART_CR1_OVER8 */
+
+ if (huart->gState == HAL_UART_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ huart->Lock = HAL_UNLOCKED;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ UART_InitCallbacksToDefault(huart);
+
+ if (huart->MspInitCallback == NULL)
+ {
+ huart->MspInitCallback = HAL_UART_MspInit;
+ }
+
+ /* Init the low level hardware */
+ huart->MspInitCallback(huart);
+#else
+ /* Init the low level hardware : GPIO, CLOCK */
+ HAL_UART_MspInit(huart);
+#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
+ }
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /* Disable the peripheral */
+ __HAL_UART_DISABLE(huart);
+
+ /* Set the UART Communication parameters */
+ UART_SetConfig(huart);
+
+ /* In Multi-Processor mode, the following bits must be kept cleared:
+ - LINEN and CLKEN bits in the USART_CR2 register,
+ - SCEN, HDSEL and IREN bits in the USART_CR3 register */
+ CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
+ CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
+
+ /* Set the USART address node */
+ CLEAR_BIT(huart->Instance->CR2, USART_CR2_ADD);
+ SET_BIT(huart->Instance->CR2, Address);
+
+ /* Set the wake up method by setting the WAKE bit in the CR1 register */
+ CLEAR_BIT(huart->Instance->CR1, USART_CR1_WAKE);
+ SET_BIT(huart->Instance->CR1, WakeUpMethod);
+
+ /* Enable the peripheral */
+ __HAL_UART_ENABLE(huart);
+
+ /* Initialize the UART state */
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->gState = HAL_UART_STATE_READY;
+ huart->RxState = HAL_UART_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief DeInitializes the UART peripheral.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart)
+{
+ /* Check the UART handle allocation */
+ if (huart == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_UART_INSTANCE(huart->Instance));
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /* Disable the Peripheral */
+ __HAL_UART_DISABLE(huart);
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ if (huart->MspDeInitCallback == NULL)
+ {
+ huart->MspDeInitCallback = HAL_UART_MspDeInit;
+ }
+ /* DeInit the low level hardware */
+ huart->MspDeInitCallback(huart);
+#else
+ /* DeInit the low level hardware */
+ HAL_UART_MspDeInit(huart);
+#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->gState = HAL_UART_STATE_RESET;
+ huart->RxState = HAL_UART_STATE_RESET;
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ /* Process Unlock */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief UART MSP Init.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+__weak void HAL_UART_MspInit(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_UART_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief UART MSP DeInit.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+__weak void HAL_UART_MspDeInit(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_UART_MspDeInit could be implemented in the user file
+ */
+}
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+/**
+ * @brief Register a User UART Callback
+ * To be used instead of the weak predefined callback
+ * @param huart uart handle
+ * @param CallbackID ID of the callback to be registered
+ * This parameter can be one of the following values:
+ * @arg @ref HAL_UART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
+ * @arg @ref HAL_UART_TX_COMPLETE_CB_ID Tx Complete Callback ID
+ * @arg @ref HAL_UART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
+ * @arg @ref HAL_UART_RX_COMPLETE_CB_ID Rx Complete Callback ID
+ * @arg @ref HAL_UART_ERROR_CB_ID Error Callback ID
+ * @arg @ref HAL_UART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
+ * @arg @ref HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID
+ * @arg @ref HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID
+ * @arg @ref HAL_UART_MSPINIT_CB_ID MspInit Callback ID
+ * @arg @ref HAL_UART_MSPDEINIT_CB_ID MspDeInit Callback ID
+ * @param pCallback pointer to the Callback function
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_RegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID, pUART_CallbackTypeDef pCallback)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ if (pCallback == NULL)
+ {
+ /* Update the error code */
+ huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+ return HAL_ERROR;
+ }
+ /* Process locked */
+ __HAL_LOCK(huart);
+
+ if (huart->gState == HAL_UART_STATE_READY)
+ {
+ switch (CallbackID)
+ {
+ case HAL_UART_TX_HALFCOMPLETE_CB_ID :
+ huart->TxHalfCpltCallback = pCallback;
+ break;
+
+ case HAL_UART_TX_COMPLETE_CB_ID :
+ huart->TxCpltCallback = pCallback;
+ break;
+
+ case HAL_UART_RX_HALFCOMPLETE_CB_ID :
+ huart->RxHalfCpltCallback = pCallback;
+ break;
+
+ case HAL_UART_RX_COMPLETE_CB_ID :
+ huart->RxCpltCallback = pCallback;
+ break;
+
+ case HAL_UART_ERROR_CB_ID :
+ huart->ErrorCallback = pCallback;
+ break;
+
+ case HAL_UART_ABORT_COMPLETE_CB_ID :
+ huart->AbortCpltCallback = pCallback;
+ break;
+
+ case HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID :
+ huart->AbortTransmitCpltCallback = pCallback;
+ break;
+
+ case HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID :
+ huart->AbortReceiveCpltCallback = pCallback;
+ break;
+
+ case HAL_UART_MSPINIT_CB_ID :
+ huart->MspInitCallback = pCallback;
+ break;
+
+ case HAL_UART_MSPDEINIT_CB_ID :
+ huart->MspDeInitCallback = pCallback;
+ break;
+
+ default :
+ /* Update the error code */
+ huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else if (huart->gState == HAL_UART_STATE_RESET)
+ {
+ switch (CallbackID)
+ {
+ case HAL_UART_MSPINIT_CB_ID :
+ huart->MspInitCallback = pCallback;
+ break;
+
+ case HAL_UART_MSPDEINIT_CB_ID :
+ huart->MspDeInitCallback = pCallback;
+ break;
+
+ default :
+ /* Update the error code */
+ huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ /* Update the error code */
+ huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+ /* Return error status */
+ status = HAL_ERROR;
+ }
+
+ /* Release Lock */
+ __HAL_UNLOCK(huart);
+
+ return status;
+}
+
+/**
+ * @brief Unregister an UART Callback
+ * UART callaback is redirected to the weak predefined callback
+ * @param huart uart handle
+ * @param CallbackID ID of the callback to be unregistered
+ * This parameter can be one of the following values:
+ * @arg @ref HAL_UART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
+ * @arg @ref HAL_UART_TX_COMPLETE_CB_ID Tx Complete Callback ID
+ * @arg @ref HAL_UART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
+ * @arg @ref HAL_UART_RX_COMPLETE_CB_ID Rx Complete Callback ID
+ * @arg @ref HAL_UART_ERROR_CB_ID Error Callback ID
+ * @arg @ref HAL_UART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
+ * @arg @ref HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID
+ * @arg @ref HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID
+ * @arg @ref HAL_UART_MSPINIT_CB_ID MspInit Callback ID
+ * @arg @ref HAL_UART_MSPDEINIT_CB_ID MspDeInit Callback ID
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_UnRegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Process locked */
+ __HAL_LOCK(huart);
+
+ if (HAL_UART_STATE_READY == huart->gState)
+ {
+ switch (CallbackID)
+ {
+ case HAL_UART_TX_HALFCOMPLETE_CB_ID :
+ huart->TxHalfCpltCallback = HAL_UART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
+ break;
+
+ case HAL_UART_TX_COMPLETE_CB_ID :
+ huart->TxCpltCallback = HAL_UART_TxCpltCallback; /* Legacy weak TxCpltCallback */
+ break;
+
+ case HAL_UART_RX_HALFCOMPLETE_CB_ID :
+ huart->RxHalfCpltCallback = HAL_UART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
+ break;
+
+ case HAL_UART_RX_COMPLETE_CB_ID :
+ huart->RxCpltCallback = HAL_UART_RxCpltCallback; /* Legacy weak RxCpltCallback */
+ break;
+
+ case HAL_UART_ERROR_CB_ID :
+ huart->ErrorCallback = HAL_UART_ErrorCallback; /* Legacy weak ErrorCallback */
+ break;
+
+ case HAL_UART_ABORT_COMPLETE_CB_ID :
+ huart->AbortCpltCallback = HAL_UART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
+ break;
+
+ case HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID :
+ huart->AbortTransmitCpltCallback = HAL_UART_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */
+ break;
+
+ case HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID :
+ huart->AbortReceiveCpltCallback = HAL_UART_AbortReceiveCpltCallback; /* Legacy weak AbortReceiveCpltCallback */
+ break;
+
+ case HAL_UART_MSPINIT_CB_ID :
+ huart->MspInitCallback = HAL_UART_MspInit; /* Legacy weak MspInitCallback */
+ break;
+
+ case HAL_UART_MSPDEINIT_CB_ID :
+ huart->MspDeInitCallback = HAL_UART_MspDeInit; /* Legacy weak MspDeInitCallback */
+ break;
+
+ default :
+ /* Update the error code */
+ huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else if (HAL_UART_STATE_RESET == huart->gState)
+ {
+ switch (CallbackID)
+ {
+ case HAL_UART_MSPINIT_CB_ID :
+ huart->MspInitCallback = HAL_UART_MspInit;
+ break;
+
+ case HAL_UART_MSPDEINIT_CB_ID :
+ huart->MspDeInitCallback = HAL_UART_MspDeInit;
+ break;
+
+ default :
+ /* Update the error code */
+ huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ /* Update the error code */
+ huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+ /* Return error status */
+ status = HAL_ERROR;
+ }
+
+ /* Release Lock */
+ __HAL_UNLOCK(huart);
+
+ return status;
+}
+
+/**
+ * @brief Register a User UART Rx Event Callback
+ * To be used instead of the weak predefined callback
+ * @param huart Uart handle
+ * @param pCallback Pointer to the Rx Event Callback function
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_RegisterRxEventCallback(UART_HandleTypeDef *huart, pUART_RxEventCallbackTypeDef pCallback)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ if (pCallback == NULL)
+ {
+ huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+ return HAL_ERROR;
+ }
+
+ /* Process locked */
+ __HAL_LOCK(huart);
+
+ if (huart->gState == HAL_UART_STATE_READY)
+ {
+ huart->RxEventCallback = pCallback;
+ }
+ else
+ {
+ huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+ status = HAL_ERROR;
+ }
+
+ /* Release Lock */
+ __HAL_UNLOCK(huart);
+
+ return status;
+}
+
+/**
+ * @brief UnRegister the UART Rx Event Callback
+ * UART Rx Event Callback is redirected to the weak HAL_UARTEx_RxEventCallback() predefined callback
+ * @param huart Uart handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_UnRegisterRxEventCallback(UART_HandleTypeDef *huart)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Process locked */
+ __HAL_LOCK(huart);
+
+ if (huart->gState == HAL_UART_STATE_READY)
+ {
+ huart->RxEventCallback = HAL_UARTEx_RxEventCallback; /* Legacy weak UART Rx Event Callback */
+ }
+ else
+ {
+ huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+ status = HAL_ERROR;
+ }
+
+ /* Release Lock */
+ __HAL_UNLOCK(huart);
+ return status;
+}
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+
+/**
+ * @}
+ */
+
+/** @defgroup UART_Exported_Functions_Group2 IO operation functions
+ * @brief UART Transmit and Receive functions
+ *
+@verbatim
+ ===============================================================================
+ ##### IO operation functions #####
+ ===============================================================================
+ This subsection provides a set of functions allowing to manage the UART asynchronous
+ and Half duplex data transfers.
+
+ (#) There are two modes of transfer:
+ (+) Blocking mode: The communication is performed in polling mode.
+ The HAL status of all data processing is returned by the same function
+ after finishing transfer.
+ (+) Non-Blocking mode: The communication is performed using Interrupts
+ or DMA, these API's return the HAL status.
+ The end of the data processing will be indicated through the
+ dedicated UART IRQ when using Interrupt mode or the DMA IRQ when
+ using DMA mode.
+ The HAL_UART_TxCpltCallback(), HAL_UART_RxCpltCallback() user callbacks
+ will be executed respectively at the end of the transmit or receive process
+ The HAL_UART_ErrorCallback()user callback will be executed when a communication error is detected.
+
+ (#) Blocking mode API's are :
+ (+) HAL_UART_Transmit()
+ (+) HAL_UART_Receive()
+
+ (#) Non-Blocking mode API's with Interrupt are :
+ (+) HAL_UART_Transmit_IT()
+ (+) HAL_UART_Receive_IT()
+ (+) HAL_UART_IRQHandler()
+
+ (#) Non-Blocking mode API's with DMA are :
+ (+) HAL_UART_Transmit_DMA()
+ (+) HAL_UART_Receive_DMA()
+ (+) HAL_UART_DMAPause()
+ (+) HAL_UART_DMAResume()
+ (+) HAL_UART_DMAStop()
+
+ (#) A set of Transfer Complete Callbacks are provided in Non_Blocking mode:
+ (+) HAL_UART_TxHalfCpltCallback()
+ (+) HAL_UART_TxCpltCallback()
+ (+) HAL_UART_RxHalfCpltCallback()
+ (+) HAL_UART_RxCpltCallback()
+ (+) HAL_UART_ErrorCallback()
+
+ (#) Non-Blocking mode transfers could be aborted using Abort API's :
+ (+) HAL_UART_Abort()
+ (+) HAL_UART_AbortTransmit()
+ (+) HAL_UART_AbortReceive()
+ (+) HAL_UART_Abort_IT()
+ (+) HAL_UART_AbortTransmit_IT()
+ (+) HAL_UART_AbortReceive_IT()
+
+ (#) For Abort services based on interrupts (HAL_UART_Abortxxx_IT), a set of Abort Complete Callbacks are provided:
+ (+) HAL_UART_AbortCpltCallback()
+ (+) HAL_UART_AbortTransmitCpltCallback()
+ (+) HAL_UART_AbortReceiveCpltCallback()
+
+ (#) A Rx Event Reception Callback (Rx event notification) is available for Non_Blocking modes of enhanced reception services:
+ (+) HAL_UARTEx_RxEventCallback()
+
+ (#) In Non-Blocking mode transfers, possible errors are split into 2 categories.
+ Errors are handled as follows :
+ (+) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is
+ to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error in Interrupt mode reception .
+ Received character is then retrieved and stored in Rx buffer, Error code is set to allow user to identify error type,
+ and HAL_UART_ErrorCallback() user callback is executed. Transfer is kept ongoing on UART side.
+ If user wants to abort it, Abort services should be called by user.
+ (+) Error is considered as Blocking : Transfer could not be completed properly and is aborted.
+ This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode.
+ Error code is set to allow user to identify error type, and HAL_UART_ErrorCallback() user callback is executed.
+
+ -@- In the Half duplex communication, it is forbidden to run the transmit
+ and receive process in parallel, the UART state HAL_UART_STATE_BUSY_TX_RX can't be useful.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Sends an amount of data in blocking mode.
+ * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
+ * the sent data is handled as a set of u16. In this case, Size must indicate the number
+ * of u16 provided through pData.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param pData Pointer to data buffer (u8 or u16 data elements).
+ * @param Size Amount of data elements (u8 or u16) to be sent
+ * @param Timeout Timeout duration
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
+{
+ uint8_t *pdata8bits;
+ uint16_t *pdata16bits;
+ uint32_t tickstart = 0U;
+
+ /* Check that a Tx process is not already ongoing */
+ if (huart->gState == HAL_UART_STATE_READY)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->gState = HAL_UART_STATE_BUSY_TX;
+
+ /* Init tickstart for timeout management */
+ tickstart = HAL_GetTick();
+
+ huart->TxXferSize = Size;
+ huart->TxXferCount = Size;
+
+ /* In case of 9bits/No Parity transfer, pData needs to be handled as a uint16_t pointer */
+ if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
+ {
+ pdata8bits = NULL;
+ pdata16bits = (uint16_t *) pData;
+ }
+ else
+ {
+ pdata8bits = pData;
+ pdata16bits = NULL;
+ }
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ while (huart->TxXferCount > 0U)
+ {
+ if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
+ {
+ return HAL_TIMEOUT;
+ }
+ if (pdata8bits == NULL)
+ {
+ huart->Instance->DR = (uint16_t)(*pdata16bits & 0x01FFU);
+ pdata16bits++;
+ }
+ else
+ {
+ huart->Instance->DR = (uint8_t)(*pdata8bits & 0xFFU);
+ pdata8bits++;
+ }
+ huart->TxXferCount--;
+ }
+
+ if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
+ {
+ return HAL_TIMEOUT;
+ }
+
+ /* At end of Tx process, restore huart->gState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Receives an amount of data in blocking mode.
+ * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
+ * the received data is handled as a set of u16. In this case, Size must indicate the number
+ * of u16 available through pData.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param pData Pointer to data buffer (u8 or u16 data elements).
+ * @param Size Amount of data elements (u8 or u16) to be received.
+ * @param Timeout Timeout duration
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
+{
+ uint8_t *pdata8bits;
+ uint16_t *pdata16bits;
+ uint32_t tickstart = 0U;
+
+ /* Check that a Rx process is not already ongoing */
+ if (huart->RxState == HAL_UART_STATE_READY)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->RxState = HAL_UART_STATE_BUSY_RX;
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ /* Init tickstart for timeout management */
+ tickstart = HAL_GetTick();
+
+ huart->RxXferSize = Size;
+ huart->RxXferCount = Size;
+
+ /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
+ if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
+ {
+ pdata8bits = NULL;
+ pdata16bits = (uint16_t *) pData;
+ }
+ else
+ {
+ pdata8bits = pData;
+ pdata16bits = NULL;
+ }
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ /* Check the remain data to be received */
+ while (huart->RxXferCount > 0U)
+ {
+ if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
+ {
+ return HAL_TIMEOUT;
+ }
+ if (pdata8bits == NULL)
+ {
+ *pdata16bits = (uint16_t)(huart->Instance->DR & 0x01FF);
+ pdata16bits++;
+ }
+ else
+ {
+ if ((huart->Init.WordLength == UART_WORDLENGTH_9B) || ((huart->Init.WordLength == UART_WORDLENGTH_8B) && (huart->Init.Parity == UART_PARITY_NONE)))
+ {
+ *pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
+ }
+ else
+ {
+ *pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
+ }
+ pdata8bits++;
+ }
+ huart->RxXferCount--;
+ }
+
+ /* At end of Rx process, restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Sends an amount of data in non blocking mode.
+ * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
+ * the sent data is handled as a set of u16. In this case, Size must indicate the number
+ * of u16 provided through pData.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param pData Pointer to data buffer (u8 or u16 data elements).
+ * @param Size Amount of data elements (u8 or u16) to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
+{
+ /* Check that a Tx process is not already ongoing */
+ if (huart->gState == HAL_UART_STATE_READY)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->pTxBuffPtr = pData;
+ huart->TxXferSize = Size;
+ huart->TxXferCount = Size;
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->gState = HAL_UART_STATE_BUSY_TX;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ /* Enable the UART Transmit data register empty Interrupt */
+ __HAL_UART_ENABLE_IT(huart, UART_IT_TXE);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Receives an amount of data in non blocking mode.
+ * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
+ * the received data is handled as a set of u16. In this case, Size must indicate the number
+ * of u16 available through pData.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param pData Pointer to data buffer (u8 or u16 data elements).
+ * @param Size Amount of data elements (u8 or u16) to be received.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
+{
+ /* Check that a Rx process is not already ongoing */
+ if (huart->RxState == HAL_UART_STATE_READY)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ /* Set Reception type to Standard reception */
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ return(UART_Start_Receive_IT(huart, pData, Size));
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Sends an amount of data in DMA mode.
+ * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
+ * the sent data is handled as a set of u16. In this case, Size must indicate the number
+ * of u16 provided through pData.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param pData Pointer to data buffer (u8 or u16 data elements).
+ * @param Size Amount of data elements (u8 or u16) to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
+{
+ uint32_t *tmp;
+
+ /* Check that a Tx process is not already ongoing */
+ if (huart->gState == HAL_UART_STATE_READY)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->pTxBuffPtr = pData;
+ huart->TxXferSize = Size;
+ huart->TxXferCount = Size;
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->gState = HAL_UART_STATE_BUSY_TX;
+
+ /* Set the UART DMA transfer complete callback */
+ huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt;
+
+ /* Set the UART DMA Half transfer complete callback */
+ huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt;
+
+ /* Set the DMA error callback */
+ huart->hdmatx->XferErrorCallback = UART_DMAError;
+
+ /* Set the DMA abort callback */
+ huart->hdmatx->XferAbortCallback = NULL;
+
+ /* Enable the UART transmit DMA channel */
+ tmp = (uint32_t *)&pData;
+ HAL_DMA_Start_IT(huart->hdmatx, *(uint32_t *)tmp, (uint32_t)&huart->Instance->DR, Size);
+
+ /* Clear the TC flag in the SR register by writing 0 to it */
+ __HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC);
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ /* Enable the DMA transfer for transmit request by setting the DMAT bit
+ in the UART CR3 register */
+ SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Receives an amount of data in DMA mode.
+ * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
+ * the received data is handled as a set of u16. In this case, Size must indicate the number
+ * of u16 available through pData.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param pData Pointer to data buffer (u8 or u16 data elements).
+ * @param Size Amount of data elements (u8 or u16) to be received.
+ * @note When the UART parity is enabled (PCE = 1) the received data contains the parity bit.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
+{
+ /* Check that a Rx process is not already ongoing */
+ if (huart->RxState == HAL_UART_STATE_READY)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ /* Set Reception type to Standard reception */
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ return(UART_Start_Receive_DMA(huart, pData, Size));
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Pauses the DMA Transfer.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart)
+{
+ uint32_t dmarequest = 0x00U;
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT);
+ if ((huart->gState == HAL_UART_STATE_BUSY_TX) && dmarequest)
+ {
+ /* Disable the UART DMA Tx request */
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+ }
+
+ dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR);
+ if ((huart->RxState == HAL_UART_STATE_BUSY_RX) && dmarequest)
+ {
+ /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* Disable the UART DMA Rx request */
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+ }
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Resumes the DMA Transfer.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart)
+{
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ if (huart->gState == HAL_UART_STATE_BUSY_TX)
+ {
+ /* Enable the UART DMA Tx request */
+ SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+ }
+
+ if (huart->RxState == HAL_UART_STATE_BUSY_RX)
+ {
+ /* Clear the Overrun flag before resuming the Rx transfer*/
+ __HAL_UART_CLEAR_OREFLAG(huart);
+
+ /* Re-enable PE and ERR (Frame error, noise error, overrun error) interrupts */
+ SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
+ SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* Enable the UART DMA Rx request */
+ SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+ }
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the DMA Transfer.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart)
+{
+ uint32_t dmarequest = 0x00U;
+ /* The Lock is not implemented on this API to allow the user application
+ to call the HAL UART API under callbacks HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback():
+ when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated
+ and the correspond call back is executed HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback()
+ */
+
+ /* Stop UART DMA Tx request if ongoing */
+ dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT);
+ if ((huart->gState == HAL_UART_STATE_BUSY_TX) && dmarequest)
+ {
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+
+ /* Abort the UART DMA Tx channel */
+ if (huart->hdmatx != NULL)
+ {
+ HAL_DMA_Abort(huart->hdmatx);
+ }
+ UART_EndTxTransfer(huart);
+ }
+
+ /* Stop UART DMA Rx request if ongoing */
+ dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR);
+ if ((huart->RxState == HAL_UART_STATE_BUSY_RX) && dmarequest)
+ {
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+ /* Abort the UART DMA Rx channel */
+ if (huart->hdmarx != NULL)
+ {
+ HAL_DMA_Abort(huart->hdmarx);
+ }
+ UART_EndRxTransfer(huart);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Receive an amount of data in blocking mode till either the expected number of data is received or an IDLE event occurs.
+ * @note HAL_OK is returned if reception is completed (expected number of data has been received)
+ * or if reception is stopped after IDLE event (less than the expected number of data has been received)
+ * In this case, RxLen output parameter indicates number of data available in reception buffer.
+ * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M = 01),
+ * the received data is handled as a set of uint16_t. In this case, Size must indicate the number
+ * of uint16_t available through pData.
+ * @param huart UART handle.
+ * @param pData Pointer to data buffer (uint8_t or uint16_t data elements).
+ * @param Size Amount of data elements (uint8_t or uint16_t) to be received.
+ * @param RxLen Number of data elements finally received (could be lower than Size, in case reception ends on IDLE event)
+ * @param Timeout Timeout duration expressed in ms (covers the whole reception sequence).
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint16_t *RxLen, uint32_t Timeout)
+{
+ uint8_t *pdata8bits;
+ uint16_t *pdata16bits;
+ uint32_t tickstart;
+
+ /* Check that a Rx process is not already ongoing */
+ if (huart->RxState == HAL_UART_STATE_READY)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ __HAL_LOCK(huart);
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->RxState = HAL_UART_STATE_BUSY_RX;
+ huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
+
+ /* Init tickstart for timeout management */
+ tickstart = HAL_GetTick();
+
+ huart->RxXferSize = Size;
+ huart->RxXferCount = Size;
+
+ /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
+ if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
+ {
+ pdata8bits = NULL;
+ pdata16bits = (uint16_t *) pData;
+ }
+ else
+ {
+ pdata8bits = pData;
+ pdata16bits = NULL;
+ }
+
+ __HAL_UNLOCK(huart);
+
+ /* Initialize output number of received elements */
+ *RxLen = 0U;
+
+ /* as long as data have to be received */
+ while (huart->RxXferCount > 0U)
+ {
+ /* Check if IDLE flag is set */
+ if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE))
+ {
+ /* Clear IDLE flag in ISR */
+ __HAL_UART_CLEAR_IDLEFLAG(huart);
+
+ /* If Set, but no data ever received, clear flag without exiting loop */
+ /* If Set, and data has already been received, this means Idle Event is valid : End reception */
+ if (*RxLen > 0U)
+ {
+ huart->RxState = HAL_UART_STATE_READY;
+
+ return HAL_OK;
+ }
+ }
+
+ /* Check if RXNE flag is set */
+ if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE))
+ {
+ if (pdata8bits == NULL)
+ {
+ *pdata16bits = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF);
+ pdata16bits++;
+ }
+ else
+ {
+ if ((huart->Init.WordLength == UART_WORDLENGTH_9B) || ((huart->Init.WordLength == UART_WORDLENGTH_8B) && (huart->Init.Parity == UART_PARITY_NONE)))
+ {
+ *pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
+ }
+ else
+ {
+ *pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
+ }
+
+ pdata8bits++;
+ }
+ /* Increment number of received elements */
+ *RxLen += 1U;
+ huart->RxXferCount--;
+ }
+
+ /* Check for the Timeout */
+ if (Timeout != HAL_MAX_DELAY)
+ {
+ if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
+ {
+ huart->RxState = HAL_UART_STATE_READY;
+
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+
+ /* Set number of received elements in output parameter : RxLen */
+ *RxLen = huart->RxXferSize - huart->RxXferCount;
+ /* At end of Rx process, restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Receive an amount of data in interrupt mode till either the expected number of data is received or an IDLE event occurs.
+ * @note Reception is initiated by this function call. Further progress of reception is achieved thanks
+ * to UART interrupts raised by RXNE and IDLE events. Callback is called at end of reception indicating
+ * number of received data elements.
+ * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M = 01),
+ * the received data is handled as a set of uint16_t. In this case, Size must indicate the number
+ * of uint16_t available through pData.
+ * @param huart UART handle.
+ * @param pData Pointer to data buffer (uint8_t or uint16_t data elements).
+ * @param Size Amount of data elements (uint8_t or uint16_t) to be received.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
+{
+ HAL_StatusTypeDef status;
+
+ /* Check that a Rx process is not already ongoing */
+ if (huart->RxState == HAL_UART_STATE_READY)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ __HAL_LOCK(huart);
+
+ /* Set Reception type to reception till IDLE Event*/
+ huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
+
+ status = UART_Start_Receive_IT(huart, pData, Size);
+
+ /* Check Rx process has been successfully started */
+ if (status == HAL_OK)
+ {
+ if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+ {
+ __HAL_UART_CLEAR_IDLEFLAG(huart);
+ SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
+ }
+ else
+ {
+ /* In case of errors already pending when reception is started,
+ Interrupts may have already been raised and lead to reception abortion.
+ (Overrun error for instance).
+ In such case Reception Type has been reset to HAL_UART_RECEPTION_STANDARD. */
+ status = HAL_ERROR;
+ }
+ }
+
+ return status;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Receive an amount of data in DMA mode till either the expected number of data is received or an IDLE event occurs.
+ * @note Reception is initiated by this function call. Further progress of reception is achieved thanks
+ * to DMA services, transferring automatically received data elements in user reception buffer and
+ * calling registered callbacks at half/end of reception. UART IDLE events are also used to consider
+ * reception phase as ended. In all cases, callback execution will indicate number of received data elements.
+ * @note When the UART parity is enabled (PCE = 1), the received data contain
+ * the parity bit (MSB position).
+ * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M = 01),
+ * the received data is handled as a set of uint16_t. In this case, Size must indicate the number
+ * of uint16_t available through pData.
+ * @param huart UART handle.
+ * @param pData Pointer to data buffer (uint8_t or uint16_t data elements).
+ * @param Size Amount of data elements (uint8_t or uint16_t) to be received.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
+{
+ HAL_StatusTypeDef status;
+
+ /* Check that a Rx process is not already ongoing */
+ if (huart->RxState == HAL_UART_STATE_READY)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ __HAL_LOCK(huart);
+
+ /* Set Reception type to reception till IDLE Event*/
+ huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
+
+ status = UART_Start_Receive_DMA(huart, pData, Size);
+
+ /* Check Rx process has been successfully started */
+ if (status == HAL_OK)
+ {
+ if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+ {
+ __HAL_UART_CLEAR_IDLEFLAG(huart);
+ SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
+ }
+ else
+ {
+ /* In case of errors already pending when reception is started,
+ Interrupts may have already been raised and lead to reception abortion.
+ (Overrun error for instance).
+ In such case Reception Type has been reset to HAL_UART_RECEPTION_STANDARD. */
+ status = HAL_ERROR;
+ }
+ }
+
+ return status;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Abort ongoing transfers (blocking mode).
+ * @param huart UART handle.
+ * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable UART Interrupts (Tx and Rx)
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_UART_Abort(UART_HandleTypeDef *huart)
+{
+ /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */
+ if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+ {
+ CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE));
+ }
+
+ /* Disable the UART DMA Tx request if enabled */
+ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
+ {
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+
+ /* Abort the UART DMA Tx channel: use blocking DMA Abort API (no callback) */
+ if (huart->hdmatx != NULL)
+ {
+ /* Set the UART DMA Abort callback to Null.
+ No call back execution at end of DMA abort procedure */
+ huart->hdmatx->XferAbortCallback = NULL;
+
+ if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK)
+ {
+ if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
+ {
+ /* Set error code to DMA */
+ huart->ErrorCode = HAL_UART_ERROR_DMA;
+
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ }
+
+ /* Disable the UART DMA Rx request if enabled */
+ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
+ {
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+ /* Abort the UART DMA Rx channel: use blocking DMA Abort API (no callback) */
+ if (huart->hdmarx != NULL)
+ {
+ /* Set the UART DMA Abort callback to Null.
+ No call back execution at end of DMA abort procedure */
+ huart->hdmarx->XferAbortCallback = NULL;
+
+ if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK)
+ {
+ if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
+ {
+ /* Set error code to DMA */
+ huart->ErrorCode = HAL_UART_ERROR_DMA;
+
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ }
+
+ /* Reset Tx and Rx transfer counters */
+ huart->TxXferCount = 0x00U;
+ huart->RxXferCount = 0x00U;
+
+ /* Reset ErrorCode */
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+
+ /* Restore huart->RxState and huart->gState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->gState = HAL_UART_STATE_READY;
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Abort ongoing Transmit transfer (blocking mode).
+ * @param huart UART handle.
+ * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable UART Interrupts (Tx)
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_UART_AbortTransmit(UART_HandleTypeDef *huart)
+{
+ /* Disable TXEIE and TCIE interrupts */
+ CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
+
+ /* Disable the UART DMA Tx request if enabled */
+ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
+ {
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+
+ /* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */
+ if (huart->hdmatx != NULL)
+ {
+ /* Set the UART DMA Abort callback to Null.
+ No call back execution at end of DMA abort procedure */
+ huart->hdmatx->XferAbortCallback = NULL;
+
+ if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK)
+ {
+ if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
+ {
+ /* Set error code to DMA */
+ huart->ErrorCode = HAL_UART_ERROR_DMA;
+
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ }
+
+ /* Reset Tx transfer counter */
+ huart->TxXferCount = 0x00U;
+
+ /* Restore huart->gState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Abort ongoing Receive transfer (blocking mode).
+ * @param huart UART handle.
+ * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable UART Interrupts (Rx)
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_UART_AbortReceive(UART_HandleTypeDef *huart)
+{
+ /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */
+ if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+ {
+ CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE));
+ }
+
+ /* Disable the UART DMA Rx request if enabled */
+ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
+ {
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+ /* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */
+ if (huart->hdmarx != NULL)
+ {
+ /* Set the UART DMA Abort callback to Null.
+ No call back execution at end of DMA abort procedure */
+ huart->hdmarx->XferAbortCallback = NULL;
+
+ if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK)
+ {
+ if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
+ {
+ /* Set error code to DMA */
+ huart->ErrorCode = HAL_UART_ERROR_DMA;
+
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ }
+
+ /* Reset Rx transfer counter */
+ huart->RxXferCount = 0x00U;
+
+ /* Restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Abort ongoing transfers (Interrupt mode).
+ * @param huart UART handle.
+ * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable UART Interrupts (Tx and Rx)
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * - At abort completion, call user abort complete callback
+ * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
+ * considered as completed only when user abort complete callback is executed (not when exiting function).
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_UART_Abort_IT(UART_HandleTypeDef *huart)
+{
+ uint32_t AbortCplt = 0x01U;
+
+ /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */
+ if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+ {
+ CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE));
+ }
+
+ /* If DMA Tx and/or DMA Rx Handles are associated to UART Handle, DMA Abort complete callbacks should be initialised
+ before any call to DMA Abort functions */
+ /* DMA Tx Handle is valid */
+ if (huart->hdmatx != NULL)
+ {
+ /* Set DMA Abort Complete callback if UART DMA Tx request if enabled.
+ Otherwise, set it to NULL */
+ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
+ {
+ huart->hdmatx->XferAbortCallback = UART_DMATxAbortCallback;
+ }
+ else
+ {
+ huart->hdmatx->XferAbortCallback = NULL;
+ }
+ }
+ /* DMA Rx Handle is valid */
+ if (huart->hdmarx != NULL)
+ {
+ /* Set DMA Abort Complete callback if UART DMA Rx request if enabled.
+ Otherwise, set it to NULL */
+ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
+ {
+ huart->hdmarx->XferAbortCallback = UART_DMARxAbortCallback;
+ }
+ else
+ {
+ huart->hdmarx->XferAbortCallback = NULL;
+ }
+ }
+
+ /* Disable the UART DMA Tx request if enabled */
+ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
+ {
+ /* Disable DMA Tx at UART level */
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+
+ /* Abort the UART DMA Tx channel : use non blocking DMA Abort API (callback) */
+ if (huart->hdmatx != NULL)
+ {
+ /* UART Tx DMA Abort callback has already been initialised :
+ will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
+
+ /* Abort DMA TX */
+ if (HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK)
+ {
+ huart->hdmatx->XferAbortCallback = NULL;
+ }
+ else
+ {
+ AbortCplt = 0x00U;
+ }
+ }
+ }
+
+ /* Disable the UART DMA Rx request if enabled */
+ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
+ {
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+ /* Abort the UART DMA Rx channel : use non blocking DMA Abort API (callback) */
+ if (huart->hdmarx != NULL)
+ {
+ /* UART Rx DMA Abort callback has already been initialised :
+ will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
+
+ /* Abort DMA RX */
+ if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
+ {
+ huart->hdmarx->XferAbortCallback = NULL;
+ AbortCplt = 0x01U;
+ }
+ else
+ {
+ AbortCplt = 0x00U;
+ }
+ }
+ }
+
+ /* if no DMA abort complete callback execution is required => call user Abort Complete callback */
+ if (AbortCplt == 0x01U)
+ {
+ /* Reset Tx and Rx transfer counters */
+ huart->TxXferCount = 0x00U;
+ huart->RxXferCount = 0x00U;
+
+ /* Reset ErrorCode */
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+
+ /* Restore huart->gState and huart->RxState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ /* As no DMA to be aborted, call directly user Abort complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /* Call registered Abort complete callback */
+ huart->AbortCpltCallback(huart);
+#else
+ /* Call legacy weak Abort complete callback */
+ HAL_UART_AbortCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Abort ongoing Transmit transfer (Interrupt mode).
+ * @param huart UART handle.
+ * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable UART Interrupts (Tx)
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * - At abort completion, call user abort complete callback
+ * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
+ * considered as completed only when user abort complete callback is executed (not when exiting function).
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_UART_AbortTransmit_IT(UART_HandleTypeDef *huart)
+{
+ /* Disable TXEIE and TCIE interrupts */
+ CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
+
+ /* Disable the UART DMA Tx request if enabled */
+ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
+ {
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+
+ /* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */
+ if (huart->hdmatx != NULL)
+ {
+ /* Set the UART DMA Abort callback :
+ will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
+ huart->hdmatx->XferAbortCallback = UART_DMATxOnlyAbortCallback;
+
+ /* Abort DMA TX */
+ if (HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK)
+ {
+ /* Call Directly huart->hdmatx->XferAbortCallback function in case of error */
+ huart->hdmatx->XferAbortCallback(huart->hdmatx);
+ }
+ }
+ else
+ {
+ /* Reset Tx transfer counter */
+ huart->TxXferCount = 0x00U;
+
+ /* Restore huart->gState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+
+ /* As no DMA to be aborted, call directly user Abort complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /* Call registered Abort Transmit Complete Callback */
+ huart->AbortTransmitCpltCallback(huart);
+#else
+ /* Call legacy weak Abort Transmit Complete Callback */
+ HAL_UART_AbortTransmitCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+ }
+ else
+ {
+ /* Reset Tx transfer counter */
+ huart->TxXferCount = 0x00U;
+
+ /* Restore huart->gState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+
+ /* As no DMA to be aborted, call directly user Abort complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /* Call registered Abort Transmit Complete Callback */
+ huart->AbortTransmitCpltCallback(huart);
+#else
+ /* Call legacy weak Abort Transmit Complete Callback */
+ HAL_UART_AbortTransmitCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Abort ongoing Receive transfer (Interrupt mode).
+ * @param huart UART handle.
+ * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable UART Interrupts (Rx)
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * - At abort completion, call user abort complete callback
+ * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
+ * considered as completed only when user abort complete callback is executed (not when exiting function).
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_UART_AbortReceive_IT(UART_HandleTypeDef *huart)
+{
+ /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */
+ if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+ {
+ CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE));
+ }
+
+ /* Disable the UART DMA Rx request if enabled */
+ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
+ {
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+ /* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */
+ if (huart->hdmarx != NULL)
+ {
+ /* Set the UART DMA Abort callback :
+ will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
+ huart->hdmarx->XferAbortCallback = UART_DMARxOnlyAbortCallback;
+
+ /* Abort DMA RX */
+ if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
+ {
+ /* Call Directly huart->hdmarx->XferAbortCallback function in case of error */
+ huart->hdmarx->XferAbortCallback(huart->hdmarx);
+ }
+ }
+ else
+ {
+ /* Reset Rx transfer counter */
+ huart->RxXferCount = 0x00U;
+
+ /* Restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ /* As no DMA to be aborted, call directly user Abort complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /* Call registered Abort Receive Complete Callback */
+ huart->AbortReceiveCpltCallback(huart);
+#else
+ /* Call legacy weak Abort Receive Complete Callback */
+ HAL_UART_AbortReceiveCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+ }
+ else
+ {
+ /* Reset Rx transfer counter */
+ huart->RxXferCount = 0x00U;
+
+ /* Restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ /* As no DMA to be aborted, call directly user Abort complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /* Call registered Abort Receive Complete Callback */
+ huart->AbortReceiveCpltCallback(huart);
+#else
+ /* Call legacy weak Abort Receive Complete Callback */
+ HAL_UART_AbortReceiveCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief This function handles UART interrupt request.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
+{
+ uint32_t isrflags = READ_REG(huart->Instance->SR);
+ uint32_t cr1its = READ_REG(huart->Instance->CR1);
+ uint32_t cr3its = READ_REG(huart->Instance->CR3);
+ uint32_t errorflags = 0x00U;
+ uint32_t dmarequest = 0x00U;
+
+ /* If no error occurs */
+ errorflags = (isrflags & (uint32_t)(USART_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_NE));
+ if (errorflags == RESET)
+ {
+ /* UART in mode Receiver -------------------------------------------------*/
+ if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
+ {
+ UART_Receive_IT(huart);
+ return;
+ }
+ }
+
+ /* If some errors occur */
+ if ((errorflags != RESET) && (((cr3its & USART_CR3_EIE) != RESET) || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET)))
+ {
+ /* UART parity error interrupt occurred ----------------------------------*/
+ if (((isrflags & USART_SR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET))
+ {
+ huart->ErrorCode |= HAL_UART_ERROR_PE;
+ }
+
+ /* UART noise error interrupt occurred -----------------------------------*/
+ if (((isrflags & USART_SR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
+ {
+ huart->ErrorCode |= HAL_UART_ERROR_NE;
+ }
+
+ /* UART frame error interrupt occurred -----------------------------------*/
+ if (((isrflags & USART_SR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
+ {
+ huart->ErrorCode |= HAL_UART_ERROR_FE;
+ }
+
+ /* UART Over-Run interrupt occurred --------------------------------------*/
+ if (((isrflags & USART_SR_ORE) != RESET) && (((cr1its & USART_CR1_RXNEIE) != RESET) || ((cr3its & USART_CR3_EIE) != RESET)))
+ {
+ huart->ErrorCode |= HAL_UART_ERROR_ORE;
+ }
+
+ /* Call UART Error Call back function if need be --------------------------*/
+ if (huart->ErrorCode != HAL_UART_ERROR_NONE)
+ {
+ /* UART in mode Receiver -----------------------------------------------*/
+ if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
+ {
+ UART_Receive_IT(huart);
+ }
+
+ /* If Overrun error occurs, or if any error occurs in DMA mode reception,
+ consider error as blocking */
+ dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR);
+ if (((huart->ErrorCode & HAL_UART_ERROR_ORE) != RESET) || dmarequest)
+ {
+ /* Blocking error : transfer is aborted
+ Set the UART state ready to be able to start again the process,
+ Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
+ UART_EndRxTransfer(huart);
+
+ /* Disable the UART DMA Rx request if enabled */
+ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
+ {
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+ /* Abort the UART DMA Rx channel */
+ if (huart->hdmarx != NULL)
+ {
+ /* Set the UART DMA Abort callback :
+ will lead to call HAL_UART_ErrorCallback() at end of DMA abort procedure */
+ huart->hdmarx->XferAbortCallback = UART_DMAAbortOnError;
+ if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
+ {
+ /* Call Directly XferAbortCallback function in case of error */
+ huart->hdmarx->XferAbortCallback(huart->hdmarx);
+ }
+ }
+ else
+ {
+ /* Call user error callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered error callback*/
+ huart->ErrorCallback(huart);
+#else
+ /*Call legacy weak error callback*/
+ HAL_UART_ErrorCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+ }
+ else
+ {
+ /* Call user error callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered error callback*/
+ huart->ErrorCallback(huart);
+#else
+ /*Call legacy weak error callback*/
+ HAL_UART_ErrorCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+ }
+ else
+ {
+ /* Non Blocking error : transfer could go on.
+ Error is notified to user through user error callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered error callback*/
+ huart->ErrorCallback(huart);
+#else
+ /*Call legacy weak error callback*/
+ HAL_UART_ErrorCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ }
+ }
+ return;
+ } /* End if some error occurs */
+
+ /* Check current reception Mode :
+ If Reception till IDLE event has been selected : */
+ if ( (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+ &&((isrflags & USART_SR_IDLE) != 0U)
+ &&((cr1its & USART_SR_IDLE) != 0U))
+ {
+ __HAL_UART_CLEAR_IDLEFLAG(huart);
+
+ /* Check if DMA mode is enabled in UART */
+ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
+ {
+ /* DMA mode enabled */
+ /* Check received length : If all expected data are received, do nothing,
+ (DMA cplt callback will be called).
+ Otherwise, if at least one data has already been received, IDLE event is to be notified to user */
+ uint16_t nb_remaining_rx_data = (uint16_t) __HAL_DMA_GET_COUNTER(huart->hdmarx);
+ if ( (nb_remaining_rx_data > 0U)
+ &&(nb_remaining_rx_data < huart->RxXferSize))
+ {
+ /* Reception is not complete */
+ huart->RxXferCount = nb_remaining_rx_data;
+
+ /* In Normal mode, end DMA xfer and HAL UART Rx process*/
+ if (huart->hdmarx->Init.Mode != DMA_CIRCULAR)
+ {
+ /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
+ CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* Disable the DMA transfer for the receiver request by resetting the DMAR bit
+ in the UART CR3 register */
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+ /* At end of Rx process, restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
+
+ /* Last bytes received, so no need as the abort is immediate */
+ (void)HAL_DMA_Abort(huart->hdmarx);
+ }
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered Rx Event callback*/
+ huart->RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount));
+#else
+ /*Call legacy weak Rx Event callback*/
+ HAL_UARTEx_RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount));
+#endif
+ }
+ return;
+ }
+ else
+ {
+ /* DMA mode not enabled */
+ /* Check received length : If all expected data are received, do nothing.
+ Otherwise, if at least one data has already been received, IDLE event is to be notified to user */
+ uint16_t nb_rx_data = huart->RxXferSize - huart->RxXferCount;
+ if ( (huart->RxXferCount > 0U)
+ &&(nb_rx_data > 0U) )
+ {
+ /* Disable the UART Parity Error Interrupt and RXNE interrupts */
+ CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
+
+ /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* Rx process is completed, restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered Rx complete callback*/
+ huart->RxEventCallback(huart, nb_rx_data);
+#else
+ /*Call legacy weak Rx Event callback*/
+ HAL_UARTEx_RxEventCallback(huart, nb_rx_data);
+#endif
+ }
+ return;
+ }
+ }
+
+ /* UART in mode Transmitter ------------------------------------------------*/
+ if (((isrflags & USART_SR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET))
+ {
+ UART_Transmit_IT(huart);
+ return;
+ }
+
+ /* UART in mode Transmitter end --------------------------------------------*/
+ if (((isrflags & USART_SR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET))
+ {
+ UART_EndTransmit_IT(huart);
+ return;
+ }
+}
+
+/**
+ * @brief Tx Transfer completed callbacks.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+__weak void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_UART_TxCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Tx Half Transfer completed callbacks.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+__weak void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_UART_TxHalfCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Rx Transfer completed callbacks.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+__weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_UART_RxCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Rx Half Transfer completed callbacks.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+__weak void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_UART_RxHalfCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief UART error callbacks.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+__weak void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_UART_ErrorCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief UART Abort Complete callback.
+ * @param huart UART handle.
+ * @retval None
+ */
+__weak void HAL_UART_AbortCpltCallback(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_UART_AbortCpltCallback can be implemented in the user file.
+ */
+}
+
+/**
+ * @brief UART Abort Complete callback.
+ * @param huart UART handle.
+ * @retval None
+ */
+__weak void HAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_UART_AbortTransmitCpltCallback can be implemented in the user file.
+ */
+}
+
+/**
+ * @brief UART Abort Receive Complete callback.
+ * @param huart UART handle.
+ * @retval None
+ */
+__weak void HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_UART_AbortReceiveCpltCallback can be implemented in the user file.
+ */
+}
+
+/**
+ * @brief Reception Event Callback (Rx event notification called after use of advanced reception service).
+ * @param huart UART handle
+ * @param Size Number of data available in application reception buffer (indicates a position in
+ * reception buffer until which, data are available)
+ * @retval None
+ */
+__weak void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+ UNUSED(Size);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_UARTEx_RxEventCallback can be implemented in the user file.
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup UART_Exported_Functions_Group3 Peripheral Control functions
+ * @brief UART control functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Peripheral Control functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control the UART:
+ (+) HAL_LIN_SendBreak() API can be helpful to transmit the break character.
+ (+) HAL_MultiProcessor_EnterMuteMode() API can be helpful to enter the UART in mute mode.
+ (+) HAL_MultiProcessor_ExitMuteMode() API can be helpful to exit the UART mute mode by software.
+ (+) HAL_HalfDuplex_EnableTransmitter() API to enable the UART transmitter and disables the UART receiver in Half Duplex mode
+ (+) HAL_HalfDuplex_EnableReceiver() API to enable the UART receiver and disables the UART transmitter in Half Duplex mode
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Transmits break characters.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart)
+{
+ /* Check the parameters */
+ assert_param(IS_UART_INSTANCE(huart->Instance));
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /* Send break characters */
+ SET_BIT(huart->Instance->CR1, USART_CR1_SBK);
+
+ huart->gState = HAL_UART_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Enters the UART in mute mode.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef *huart)
+{
+ /* Check the parameters */
+ assert_param(IS_UART_INSTANCE(huart->Instance));
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /* Enable the USART mute mode by setting the RWU bit in the CR1 register */
+ SET_BIT(huart->Instance->CR1, USART_CR1_RWU);
+
+ huart->gState = HAL_UART_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Exits the UART mute mode: wake up software.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_MultiProcessor_ExitMuteMode(UART_HandleTypeDef *huart)
+{
+ /* Check the parameters */
+ assert_param(IS_UART_INSTANCE(huart->Instance));
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /* Disable the USART mute mode by clearing the RWU bit in the CR1 register */
+ CLEAR_BIT(huart->Instance->CR1, USART_CR1_RWU);
+
+ huart->gState = HAL_UART_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Enables the UART transmitter and disables the UART receiver.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart)
+{
+ uint32_t tmpreg = 0x00U;
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /*-------------------------- USART CR1 Configuration -----------------------*/
+ tmpreg = huart->Instance->CR1;
+
+ /* Clear TE and RE bits */
+ tmpreg &= (uint32_t)~((uint32_t)(USART_CR1_TE | USART_CR1_RE));
+
+ /* Enable the USART's transmit interface by setting the TE bit in the USART CR1 register */
+ tmpreg |= (uint32_t)USART_CR1_TE;
+
+ /* Write to USART CR1 */
+ WRITE_REG(huart->Instance->CR1, (uint32_t)tmpreg);
+
+ huart->gState = HAL_UART_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Enables the UART receiver and disables the UART transmitter.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart)
+{
+ uint32_t tmpreg = 0x00U;
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /*-------------------------- USART CR1 Configuration -----------------------*/
+ tmpreg = huart->Instance->CR1;
+
+ /* Clear TE and RE bits */
+ tmpreg &= (uint32_t)~((uint32_t)(USART_CR1_TE | USART_CR1_RE));
+
+ /* Enable the USART's receive interface by setting the RE bit in the USART CR1 register */
+ tmpreg |= (uint32_t)USART_CR1_RE;
+
+ /* Write to USART CR1 */
+ WRITE_REG(huart->Instance->CR1, (uint32_t)tmpreg);
+
+ huart->gState = HAL_UART_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup UART_Exported_Functions_Group4 Peripheral State and Errors functions
+ * @brief UART State and Errors functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Peripheral State and Errors functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to return the State of
+ UART communication process, return Peripheral Errors occurred during communication
+ process
+ (+) HAL_UART_GetState() API can be helpful to check in run-time the state of the UART peripheral.
+ (+) HAL_UART_GetError() check in run-time errors that could be occurred during communication.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Returns the UART state.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL state
+ */
+HAL_UART_StateTypeDef HAL_UART_GetState(UART_HandleTypeDef *huart)
+{
+ uint32_t temp1 = 0x00U, temp2 = 0x00U;
+ temp1 = huart->gState;
+ temp2 = huart->RxState;
+
+ return (HAL_UART_StateTypeDef)(temp1 | temp2);
+}
+
+/**
+ * @brief Return the UART error code
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART.
+ * @retval UART Error Code
+ */
+uint32_t HAL_UART_GetError(UART_HandleTypeDef *huart)
+{
+ return huart->ErrorCode;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup UART_Private_Functions UART Private Functions
+ * @{
+ */
+
+/**
+ * @brief Initialize the callbacks to their default values.
+ * @param huart UART handle.
+ * @retval none
+ */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+void UART_InitCallbacksToDefault(UART_HandleTypeDef *huart)
+{
+ /* Init the UART Callback settings */
+ huart->TxHalfCpltCallback = HAL_UART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
+ huart->TxCpltCallback = HAL_UART_TxCpltCallback; /* Legacy weak TxCpltCallback */
+ huart->RxHalfCpltCallback = HAL_UART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
+ huart->RxCpltCallback = HAL_UART_RxCpltCallback; /* Legacy weak RxCpltCallback */
+ huart->ErrorCallback = HAL_UART_ErrorCallback; /* Legacy weak ErrorCallback */
+ huart->AbortCpltCallback = HAL_UART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
+ huart->AbortTransmitCpltCallback = HAL_UART_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */
+ huart->AbortReceiveCpltCallback = HAL_UART_AbortReceiveCpltCallback; /* Legacy weak AbortReceiveCpltCallback */
+ huart->RxEventCallback = HAL_UARTEx_RxEventCallback; /* Legacy weak RxEventCallback */
+
+}
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+
+/**
+ * @brief DMA UART transmit process complete callback.
+ * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+ /* DMA Normal mode*/
+ if ((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
+ {
+ huart->TxXferCount = 0x00U;
+
+ /* Disable the DMA transfer for transmit request by setting the DMAT bit
+ in the UART CR3 register */
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+
+ /* Enable the UART Transmit Complete Interrupt */
+ SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
+
+ }
+ /* DMA Circular mode */
+ else
+ {
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered Tx complete callback*/
+ huart->TxCpltCallback(huart);
+#else
+ /*Call legacy weak Tx complete callback*/
+ HAL_UART_TxCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+}
+
+/**
+ * @brief DMA UART transmit process half complete callback
+ * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered Tx complete callback*/
+ huart->TxHalfCpltCallback(huart);
+#else
+ /*Call legacy weak Tx complete callback*/
+ HAL_UART_TxHalfCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief DMA UART receive process complete callback.
+ * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+ /* DMA Normal mode*/
+ if ((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
+ {
+ huart->RxXferCount = 0U;
+
+ /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* Disable the DMA transfer for the receiver request by setting the DMAR bit
+ in the UART CR3 register */
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+ /* At end of Rx process, restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+
+ /* If Reception till IDLE event has been selected, Disable IDLE Interrupt */
+ if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+ {
+ CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
+ }
+ }
+
+ /* Check current reception Mode :
+ If Reception till IDLE event has been selected : use Rx Event callback */
+ if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+ {
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered Rx Event callback*/
+ huart->RxEventCallback(huart, huart->RxXferSize);
+#else
+ /*Call legacy weak Rx Event callback*/
+ HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+ else
+ {
+ /* In other cases : use Rx Complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered Rx complete callback*/
+ huart->RxCpltCallback(huart);
+#else
+ /*Call legacy weak Rx complete callback*/
+ HAL_UART_RxCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+}
+
+/**
+ * @brief DMA UART receive process half complete callback
+ * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+ /* Check current reception Mode :
+ If Reception till IDLE event has been selected : use Rx Event callback */
+ if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+ {
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered Rx Event callback*/
+ huart->RxEventCallback(huart, huart->RxXferSize/2U);
+#else
+ /*Call legacy weak Rx Event callback*/
+ HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize/2U);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+ else
+ {
+ /* In other cases : use Rx Half Complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered Rx Half complete callback*/
+ huart->RxHalfCpltCallback(huart);
+#else
+ /*Call legacy weak Rx Half complete callback*/
+ HAL_UART_RxHalfCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+}
+
+/**
+ * @brief DMA UART communication error callback.
+ * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void UART_DMAError(DMA_HandleTypeDef *hdma)
+{
+ uint32_t dmarequest = 0x00U;
+ UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+ /* Stop UART DMA Tx request if ongoing */
+ dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT);
+ if ((huart->gState == HAL_UART_STATE_BUSY_TX) && dmarequest)
+ {
+ huart->TxXferCount = 0x00U;
+ UART_EndTxTransfer(huart);
+ }
+
+ /* Stop UART DMA Rx request if ongoing */
+ dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR);
+ if ((huart->RxState == HAL_UART_STATE_BUSY_RX) && dmarequest)
+ {
+ huart->RxXferCount = 0x00U;
+ UART_EndRxTransfer(huart);
+ }
+
+ huart->ErrorCode |= HAL_UART_ERROR_DMA;
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered error callback*/
+ huart->ErrorCallback(huart);
+#else
+ /*Call legacy weak error callback*/
+ HAL_UART_ErrorCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief This function handles UART Communication Timeout.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param Flag specifies the UART flag to check.
+ * @param Status The new Flag status (SET or RESET).
+ * @param Tickstart Tick start value
+ * @param Timeout Timeout duration
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout)
+{
+ /* Wait until flag is set */
+ while ((__HAL_UART_GET_FLAG(huart, Flag) ? SET : RESET) == Status)
+ {
+ /* Check for the Timeout */
+ if (Timeout != HAL_MAX_DELAY)
+ {
+ if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout))
+ {
+ /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
+ CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE));
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ huart->gState = HAL_UART_STATE_READY;
+ huart->RxState = HAL_UART_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief Start Receive operation in interrupt mode.
+ * @note This function could be called by all HAL UART API providing reception in Interrupt mode.
+ * @note When calling this function, parameters validity is considered as already checked,
+ * i.e. Rx State, buffer address, ...
+ * UART Handle is assumed as Locked.
+ * @param huart UART handle.
+ * @param pData Pointer to data buffer (u8 or u16 data elements).
+ * @param Size Amount of data elements (u8 or u16) to be received.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef UART_Start_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
+{
+ huart->pRxBuffPtr = pData;
+ huart->RxXferSize = Size;
+ huart->RxXferCount = Size;
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->RxState = HAL_UART_STATE_BUSY_RX;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ /* Enable the UART Parity Error Interrupt */
+ __HAL_UART_ENABLE_IT(huart, UART_IT_PE);
+
+ /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
+ __HAL_UART_ENABLE_IT(huart, UART_IT_ERR);
+
+ /* Enable the UART Data Register not empty Interrupt */
+ __HAL_UART_ENABLE_IT(huart, UART_IT_RXNE);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Start Receive operation in DMA mode.
+ * @note This function could be called by all HAL UART API providing reception in DMA mode.
+ * @note When calling this function, parameters validity is considered as already checked,
+ * i.e. Rx State, buffer address, ...
+ * UART Handle is assumed as Locked.
+ * @param huart UART handle.
+ * @param pData Pointer to data buffer (u8 or u16 data elements).
+ * @param Size Amount of data elements (u8 or u16) to be received.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef UART_Start_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
+{
+ uint32_t *tmp;
+
+ huart->pRxBuffPtr = pData;
+ huart->RxXferSize = Size;
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->RxState = HAL_UART_STATE_BUSY_RX;
+
+ /* Set the UART DMA transfer complete callback */
+ huart->hdmarx->XferCpltCallback = UART_DMAReceiveCplt;
+
+ /* Set the UART DMA Half transfer complete callback */
+ huart->hdmarx->XferHalfCpltCallback = UART_DMARxHalfCplt;
+
+ /* Set the DMA error callback */
+ huart->hdmarx->XferErrorCallback = UART_DMAError;
+
+ /* Set the DMA abort callback */
+ huart->hdmarx->XferAbortCallback = NULL;
+
+ /* Enable the DMA stream */
+ tmp = (uint32_t *)&pData;
+ HAL_DMA_Start_IT(huart->hdmarx, (uint32_t)&huart->Instance->DR, *(uint32_t *)tmp, Size);
+
+ /* Clear the Overrun flag just before enabling the DMA Rx request: can be mandatory for the second transfer */
+ __HAL_UART_CLEAR_OREFLAG(huart);
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ /* Enable the UART Parity Error Interrupt */
+ SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
+
+ /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
+ SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* Enable the DMA transfer for the receiver request by setting the DMAR bit
+ in the UART CR3 register */
+ SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief End ongoing Tx transfer on UART peripheral (following error detection or Transmit completion).
+ * @param huart UART handle.
+ * @retval None
+ */
+static void UART_EndTxTransfer(UART_HandleTypeDef *huart)
+{
+ /* Disable TXEIE and TCIE interrupts */
+ CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
+
+ /* At end of Tx process, restore huart->gState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+}
+
+/**
+ * @brief End ongoing Rx transfer on UART peripheral (following error detection or Reception completion).
+ * @param huart UART handle.
+ * @retval None
+ */
+static void UART_EndRxTransfer(UART_HandleTypeDef *huart)
+{
+ /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* In case of reception waiting for IDLE event, disable also the IDLE IE interrupt source */
+ if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+ {
+ CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
+ }
+
+ /* At end of Rx process, restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+}
+
+/**
+ * @brief DMA UART communication abort callback, when initiated by HAL services on Error
+ * (To be called at end of DMA Abort procedure following error occurrence).
+ * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+ huart->RxXferCount = 0x00U;
+ huart->TxXferCount = 0x00U;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered error callback*/
+ huart->ErrorCallback(huart);
+#else
+ /*Call legacy weak error callback*/
+ HAL_UART_ErrorCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief DMA UART Tx communication abort callback, when initiated by user
+ * (To be called at end of DMA Tx Abort procedure following user abort request).
+ * @note When this callback is executed, User Abort complete call back is called only if no
+ * Abort still ongoing for Rx DMA Handle.
+ * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+ huart->hdmatx->XferAbortCallback = NULL;
+
+ /* Check if an Abort process is still ongoing */
+ if (huart->hdmarx != NULL)
+ {
+ if (huart->hdmarx->XferAbortCallback != NULL)
+ {
+ return;
+ }
+ }
+
+ /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
+ huart->TxXferCount = 0x00U;
+ huart->RxXferCount = 0x00U;
+
+ /* Reset ErrorCode */
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+
+ /* Restore huart->gState and huart->RxState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ /* Call user Abort complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /* Call registered Abort complete callback */
+ huart->AbortCpltCallback(huart);
+#else
+ /* Call legacy weak Abort complete callback */
+ HAL_UART_AbortCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief DMA UART Rx communication abort callback, when initiated by user
+ * (To be called at end of DMA Rx Abort procedure following user abort request).
+ * @note When this callback is executed, User Abort complete call back is called only if no
+ * Abort still ongoing for Tx DMA Handle.
+ * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+ huart->hdmarx->XferAbortCallback = NULL;
+
+ /* Check if an Abort process is still ongoing */
+ if (huart->hdmatx != NULL)
+ {
+ if (huart->hdmatx->XferAbortCallback != NULL)
+ {
+ return;
+ }
+ }
+
+ /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
+ huart->TxXferCount = 0x00U;
+ huart->RxXferCount = 0x00U;
+
+ /* Reset ErrorCode */
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+
+ /* Restore huart->gState and huart->RxState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ /* Call user Abort complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /* Call registered Abort complete callback */
+ huart->AbortCpltCallback(huart);
+#else
+ /* Call legacy weak Abort complete callback */
+ HAL_UART_AbortCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief DMA UART Tx communication abort callback, when initiated by user by a call to
+ * HAL_UART_AbortTransmit_IT API (Abort only Tx transfer)
+ * (This callback is executed at end of DMA Tx Abort procedure following user abort request,
+ * and leads to user Tx Abort Complete callback execution).
+ * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+ huart->TxXferCount = 0x00U;
+
+ /* Restore huart->gState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+
+ /* Call user Abort complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /* Call registered Abort Transmit Complete Callback */
+ huart->AbortTransmitCpltCallback(huart);
+#else
+ /* Call legacy weak Abort Transmit Complete Callback */
+ HAL_UART_AbortTransmitCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief DMA UART Rx communication abort callback, when initiated by user by a call to
+ * HAL_UART_AbortReceive_IT API (Abort only Rx transfer)
+ * (This callback is executed at end of DMA Rx Abort procedure following user abort request,
+ * and leads to user Rx Abort Complete callback execution).
+ * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+ huart->RxXferCount = 0x00U;
+
+ /* Restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ /* Call user Abort complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /* Call registered Abort Receive Complete Callback */
+ huart->AbortReceiveCpltCallback(huart);
+#else
+ /* Call legacy weak Abort Receive Complete Callback */
+ HAL_UART_AbortReceiveCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief Sends an amount of data in non blocking mode.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart)
+{
+ uint16_t *tmp;
+
+ /* Check that a Tx process is ongoing */
+ if (huart->gState == HAL_UART_STATE_BUSY_TX)
+ {
+ if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
+ {
+ tmp = (uint16_t *) huart->pTxBuffPtr;
+ huart->Instance->DR = (uint16_t)(*tmp & (uint16_t)0x01FF);
+ huart->pTxBuffPtr += 2U;
+ }
+ else
+ {
+ huart->Instance->DR = (uint8_t)(*huart->pTxBuffPtr++ & (uint8_t)0x00FF);
+ }
+
+ if (--huart->TxXferCount == 0U)
+ {
+ /* Disable the UART Transmit Complete Interrupt */
+ __HAL_UART_DISABLE_IT(huart, UART_IT_TXE);
+
+ /* Enable the UART Transmit Complete Interrupt */
+ __HAL_UART_ENABLE_IT(huart, UART_IT_TC);
+ }
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Wraps up transmission in non blocking mode.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart)
+{
+ /* Disable the UART Transmit Complete Interrupt */
+ __HAL_UART_DISABLE_IT(huart, UART_IT_TC);
+
+ /* Tx process is ended, restore huart->gState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered Tx complete callback*/
+ huart->TxCpltCallback(huart);
+#else
+ /*Call legacy weak Tx complete callback*/
+ HAL_UART_TxCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Receives an amount of data in non blocking mode
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart)
+{
+ uint8_t *pdata8bits;
+ uint16_t *pdata16bits;
+
+ /* Check that a Rx process is ongoing */
+ if (huart->RxState == HAL_UART_STATE_BUSY_RX)
+ {
+ if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
+ {
+ pdata8bits = NULL;
+ pdata16bits = (uint16_t *) huart->pRxBuffPtr;
+ *pdata16bits = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF);
+ huart->pRxBuffPtr += 2U;
+ }
+ else
+ {
+ pdata8bits = (uint8_t *) huart->pRxBuffPtr;
+ pdata16bits = NULL;
+
+ if ((huart->Init.WordLength == UART_WORDLENGTH_9B) || ((huart->Init.WordLength == UART_WORDLENGTH_8B) && (huart->Init.Parity == UART_PARITY_NONE)))
+ {
+ *pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
+ }
+ else
+ {
+ *pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
+ }
+ huart->pRxBuffPtr += 1U;
+ }
+
+ if (--huart->RxXferCount == 0U)
+ {
+ /* Disable the UART Data Register not empty Interrupt */
+ __HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
+
+ /* Disable the UART Parity Error Interrupt */
+ __HAL_UART_DISABLE_IT(huart, UART_IT_PE);
+
+ /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
+ __HAL_UART_DISABLE_IT(huart, UART_IT_ERR);
+
+ /* Rx process is completed, restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+
+ /* Check current reception Mode :
+ If Reception till IDLE event has been selected : */
+ if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+ {
+ /* Set reception type to Standard */
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ /* Disable IDLE interrupt */
+ CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
+
+ /* Check if IDLE flag is set */
+ if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE))
+ {
+ /* Clear IDLE flag in ISR */
+ __HAL_UART_CLEAR_IDLEFLAG(huart);
+ }
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered Rx Event callback*/
+ huart->RxEventCallback(huart, huart->RxXferSize);
+#else
+ /*Call legacy weak Rx Event callback*/
+ HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
+#endif
+ }
+ else
+ {
+ /* Standard reception API called */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered Rx complete callback*/
+ huart->RxCpltCallback(huart);
+#else
+ /*Call legacy weak Rx complete callback*/
+ HAL_UART_RxCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+
+ return HAL_OK;
+ }
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Configures the UART peripheral.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+static void UART_SetConfig(UART_HandleTypeDef *huart)
+{
+ uint32_t tmpreg;
+ uint32_t pclk;
+
+ /* Check the parameters */
+ assert_param(IS_UART_BAUDRATE(huart->Init.BaudRate));
+ assert_param(IS_UART_STOPBITS(huart->Init.StopBits));
+ assert_param(IS_UART_PARITY(huart->Init.Parity));
+ assert_param(IS_UART_MODE(huart->Init.Mode));
+
+ /*-------------------------- USART CR2 Configuration -----------------------*/
+ /* Configure the UART Stop Bits: Set STOP[13:12] bits
+ according to huart->Init.StopBits value */
+ MODIFY_REG(huart->Instance->CR2, USART_CR2_STOP, huart->Init.StopBits);
+
+ /*-------------------------- USART CR1 Configuration -----------------------*/
+ /* Configure the UART Word Length, Parity and mode:
+ Set the M bits according to huart->Init.WordLength value
+ Set PCE and PS bits according to huart->Init.Parity value
+ Set TE and RE bits according to huart->Init.Mode value
+ Set OVER8 bit according to huart->Init.OverSampling value */
+
+#if defined(USART_CR1_OVER8)
+ tmpreg = (uint32_t)huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode | huart->Init.OverSampling;
+ MODIFY_REG(huart->Instance->CR1,
+ (uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8),
+ tmpreg);
+#else
+ tmpreg = (uint32_t)huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode;
+ MODIFY_REG(huart->Instance->CR1,
+ (uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE),
+ tmpreg);
+#endif /* USART_CR1_OVER8 */
+
+ /*-------------------------- USART CR3 Configuration -----------------------*/
+ /* Configure the UART HFC: Set CTSE and RTSE bits according to huart->Init.HwFlowCtl value */
+ MODIFY_REG(huart->Instance->CR3, (USART_CR3_RTSE | USART_CR3_CTSE), huart->Init.HwFlowCtl);
+
+
+ if(huart->Instance == USART1)
+ {
+ pclk = HAL_RCC_GetPCLK2Freq();
+ }
+ else
+ {
+ pclk = HAL_RCC_GetPCLK1Freq();
+ }
+
+ /*-------------------------- USART BRR Configuration ---------------------*/
+#if defined(USART_CR1_OVER8)
+ if (huart->Init.OverSampling == UART_OVERSAMPLING_8)
+ {
+ huart->Instance->BRR = UART_BRR_SAMPLING8(pclk, huart->Init.BaudRate);
+ }
+ else
+ {
+ huart->Instance->BRR = UART_BRR_SAMPLING16(pclk, huart->Init.BaudRate);
+ }
+#else
+ huart->Instance->BRR = UART_BRR_SAMPLING16(pclk, huart->Init.BaudRate);
+#endif /* USART_CR1_OVER8 */
+}
+
+/**
+ * @}
+ */
+
+#endif /* HAL_UART_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/