Index: ctrl/firmware/Main/CubeMX/Core/Inc/stm32h7xx_it.h
===================================================================
--- ctrl/firmware/Main/CubeMX/Core/Inc/stm32h7xx_it.h	(revision 63)
+++ ctrl/firmware/Main/CubeMX/Core/Inc/stm32h7xx_it.h	(revision 64)
@@ -54,4 +54,6 @@
 void DebugMon_Handler(void);
 void DMA1_Stream0_IRQHandler(void);
+void DMA1_Stream1_IRQHandler(void);
+void DMA1_Stream2_IRQHandler(void);
 void USART3_IRQHandler(void);
 void SDMMC1_IRQHandler(void);
Index: ctrl/firmware/Main/CubeMX/Core/Src/app_threadx.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Core/Src/app_threadx.c	(revision 63)
+++ ctrl/firmware/Main/CubeMX/Core/Src/app_threadx.c	(revision 64)
@@ -82,14 +82,14 @@
   /* USER CODE BEGIN App_ThreadX_Init */
 
-  // Allocate the stack for main thread
+  // Allocate the stack for key thread
   ret = tx_byte_allocate(byte_pool, &keys_thread_pointer, KEYS_THREAD_STACK_SIZE_BYTES, TX_NO_WAIT);
   if (ret != TX_SUCCESS) { printf("Cannot allocate bytes of memory!\n"); return ret; }
 
   char* scan_keys_thread_name = "Scan Keys Thread";
-  ret = tx_thread_create(&scan_keys_thread_ptr, scan_keys_thread_name, scanKeysThread, 0x0001,	keys_thread_pointer, KEYS_THREAD_STACK_SIZE_BYTES, TX_MAX_PRIORITIES-1, TX_MAX_PRIORITIES-1, TX_NO_TIME_SLICE, TX_AUTO_START);
+  ret = tx_thread_create(&scan_keys_thread_ptr, scan_keys_thread_name, scanKeysThread, 0x0001, keys_thread_pointer, KEYS_THREAD_STACK_SIZE_BYTES, TX_MAX_PRIORITIES-1, TX_MAX_PRIORITIES-1, TX_NO_TIME_SLICE, TX_AUTO_START);
   if (ret != TX_SUCCESS) { printf("Cannot create %s!\n", scan_keys_thread_name); return ret; }
 
 
-
+  // Allocate the stack for gsm thread
   ret = tx_byte_allocate(byte_pool, &gsm_thread_pointer, GSM_THREAD_STACK_SIZE_BYTES, TX_NO_WAIT);
   if (ret != TX_SUCCESS) { printf("Cannot allocate bytes of memory!\n"); return ret; }
Index: ctrl/firmware/Main/CubeMX/Core/Src/dma.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Core/Src/dma.c	(revision 63)
+++ ctrl/firmware/Main/CubeMX/Core/Src/dma.c	(revision 64)
@@ -47,4 +47,10 @@
   HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 0, 0);
   HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);
+  /* DMA1_Stream1_IRQn interrupt configuration */
+  HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 0, 0);
+  HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);
+  /* DMA1_Stream2_IRQn interrupt configuration */
+  HAL_NVIC_SetPriority(DMA1_Stream2_IRQn, 0, 0);
+  HAL_NVIC_EnableIRQ(DMA1_Stream2_IRQn);
 
 }
Index: ctrl/firmware/Main/CubeMX/Core/Src/stm32h7xx_it.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Core/Src/stm32h7xx_it.c	(revision 63)
+++ ctrl/firmware/Main/CubeMX/Core/Src/stm32h7xx_it.c	(revision 64)
@@ -62,4 +62,6 @@
 extern DMA_HandleTypeDef hdma_spi4_tx;
 extern SPI_HandleTypeDef hspi4;
+extern DMA_HandleTypeDef hdma_usart3_rx;
+extern DMA_HandleTypeDef hdma_usart3_tx;
 extern UART_HandleTypeDef huart3;
 extern TIM_HandleTypeDef htim7;
@@ -182,4 +184,32 @@
 
 /**
+  * @brief This function handles DMA1 stream1 global interrupt.
+  */
+void DMA1_Stream1_IRQHandler(void)
+{
+  /* USER CODE BEGIN DMA1_Stream1_IRQn 0 */
+
+  /* USER CODE END DMA1_Stream1_IRQn 0 */
+  HAL_DMA_IRQHandler(&hdma_usart3_rx);
+  /* USER CODE BEGIN DMA1_Stream1_IRQn 1 */
+
+  /* USER CODE END DMA1_Stream1_IRQn 1 */
+}
+
+/**
+  * @brief This function handles DMA1 stream2 global interrupt.
+  */
+void DMA1_Stream2_IRQHandler(void)
+{
+  /* USER CODE BEGIN DMA1_Stream2_IRQn 0 */
+
+  /* USER CODE END DMA1_Stream2_IRQn 0 */
+  HAL_DMA_IRQHandler(&hdma_usart3_tx);
+  /* USER CODE BEGIN DMA1_Stream2_IRQn 1 */
+
+  /* USER CODE END DMA1_Stream2_IRQn 1 */
+}
+
+/**
   * @brief This function handles USART3 global interrupt.
   */
@@ -239,10 +269,19 @@
 /* USER CODE BEGIN 1 */
 
-void HAL_UART_RxCpltCallback(UART_HandleTypeDef * huart)
-{
-	if (huart->Instance == USART3) gsmUnitSentData();
-}
-
 //------------------------------------------------------------------------------
 
+void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
+{
+	if (huart->Instance == USART3) gsmUnitSentData(Size);
+}
+
+//------------------------------------------------------------------------------
+
+/*void HAL_UART_RxCpltCallback(UART_HandleTypeDef * huart)
+{
+	//if (huart->Instance == USART3) gsmUnitSentData();
+}*/
+
+//------------------------------------------------------------------------------
+
 /* USER CODE END 1 */
Index: ctrl/firmware/Main/CubeMX/Core/Src/usart.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Core/Src/usart.c	(revision 63)
+++ ctrl/firmware/Main/CubeMX/Core/Src/usart.c	(revision 64)
@@ -26,4 +26,6 @@
 
 UART_HandleTypeDef huart3;
+DMA_HandleTypeDef hdma_usart3_rx;
+DMA_HandleTypeDef hdma_usart3_tx;
 
 /* USART3 init function */
@@ -119,4 +121,41 @@
     HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
 
+    /* USART3 DMA Init */
+    /* USART3_RX Init */
+    hdma_usart3_rx.Instance = DMA1_Stream1;
+    hdma_usart3_rx.Init.Request = DMA_REQUEST_USART3_RX;
+    hdma_usart3_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
+    hdma_usart3_rx.Init.PeriphInc = DMA_PINC_DISABLE;
+    hdma_usart3_rx.Init.MemInc = DMA_MINC_ENABLE;
+    hdma_usart3_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
+    hdma_usart3_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
+    hdma_usart3_rx.Init.Mode = DMA_CIRCULAR;
+    hdma_usart3_rx.Init.Priority = DMA_PRIORITY_LOW;
+    hdma_usart3_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
+    if (HAL_DMA_Init(&hdma_usart3_rx) != HAL_OK)
+    {
+      Error_Handler();
+    }
+
+    __HAL_LINKDMA(uartHandle,hdmarx,hdma_usart3_rx);
+
+    /* USART3_TX Init */
+    hdma_usart3_tx.Instance = DMA1_Stream2;
+    hdma_usart3_tx.Init.Request = DMA_REQUEST_USART3_TX;
+    hdma_usart3_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
+    hdma_usart3_tx.Init.PeriphInc = DMA_PINC_DISABLE;
+    hdma_usart3_tx.Init.MemInc = DMA_MINC_ENABLE;
+    hdma_usart3_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
+    hdma_usart3_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
+    hdma_usart3_tx.Init.Mode = DMA_NORMAL;
+    hdma_usart3_tx.Init.Priority = DMA_PRIORITY_HIGH;
+    hdma_usart3_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
+    if (HAL_DMA_Init(&hdma_usart3_tx) != HAL_OK)
+    {
+      Error_Handler();
+    }
+
+    __HAL_LINKDMA(uartHandle,hdmatx,hdma_usart3_tx);
+
     /* USART3 interrupt Init */
     HAL_NVIC_SetPriority(USART3_IRQn, 0, 0);
@@ -147,4 +186,8 @@
     HAL_GPIO_DeInit(GPIOD, GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_11|GPIO_PIN_12);
 
+    /* USART3 DMA DeInit */
+    HAL_DMA_DeInit(uartHandle->hdmarx);
+    HAL_DMA_DeInit(uartHandle->hdmatx);
+
     /* USART3 interrupt Deinit */
     HAL_NVIC_DisableIRQ(USART3_IRQn);
Index: ctrl/firmware/Main/CubeMX/charger.ioc
===================================================================
--- ctrl/firmware/Main/CubeMX/charger.ioc	(revision 63)
+++ ctrl/firmware/Main/CubeMX/charger.ioc	(revision 64)
@@ -8,5 +8,7 @@
 CORTEX_M7.default_mode_Activation=1
 Dma.Request0=SPI4_TX
-Dma.RequestsNb=1
+Dma.Request1=USART3_RX
+Dma.Request2=USART3_TX
+Dma.RequestsNb=3
 Dma.SPI4_TX.0.Direction=DMA_MEMORY_TO_PERIPH
 Dma.SPI4_TX.0.EventEnable=DISABLE
@@ -27,4 +29,40 @@
 Dma.SPI4_TX.0.SyncRequestNumber=1
 Dma.SPI4_TX.0.SyncSignalID=NONE
+Dma.USART3_RX.1.Direction=DMA_PERIPH_TO_MEMORY
+Dma.USART3_RX.1.EventEnable=DISABLE
+Dma.USART3_RX.1.FIFOMode=DMA_FIFOMODE_DISABLE
+Dma.USART3_RX.1.Instance=DMA1_Stream1
+Dma.USART3_RX.1.MemDataAlignment=DMA_MDATAALIGN_BYTE
+Dma.USART3_RX.1.MemInc=DMA_MINC_ENABLE
+Dma.USART3_RX.1.Mode=DMA_CIRCULAR
+Dma.USART3_RX.1.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
+Dma.USART3_RX.1.PeriphInc=DMA_PINC_DISABLE
+Dma.USART3_RX.1.Polarity=HAL_DMAMUX_REQ_GEN_RISING
+Dma.USART3_RX.1.Priority=DMA_PRIORITY_LOW
+Dma.USART3_RX.1.RequestNumber=1
+Dma.USART3_RX.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber
+Dma.USART3_RX.1.SignalID=NONE
+Dma.USART3_RX.1.SyncEnable=DISABLE
+Dma.USART3_RX.1.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT
+Dma.USART3_RX.1.SyncRequestNumber=1
+Dma.USART3_RX.1.SyncSignalID=NONE
+Dma.USART3_TX.2.Direction=DMA_MEMORY_TO_PERIPH
+Dma.USART3_TX.2.EventEnable=DISABLE
+Dma.USART3_TX.2.FIFOMode=DMA_FIFOMODE_DISABLE
+Dma.USART3_TX.2.Instance=DMA1_Stream2
+Dma.USART3_TX.2.MemDataAlignment=DMA_MDATAALIGN_BYTE
+Dma.USART3_TX.2.MemInc=DMA_MINC_ENABLE
+Dma.USART3_TX.2.Mode=DMA_NORMAL
+Dma.USART3_TX.2.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
+Dma.USART3_TX.2.PeriphInc=DMA_PINC_DISABLE
+Dma.USART3_TX.2.Polarity=HAL_DMAMUX_REQ_GEN_RISING
+Dma.USART3_TX.2.Priority=DMA_PRIORITY_HIGH
+Dma.USART3_TX.2.RequestNumber=1
+Dma.USART3_TX.2.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber
+Dma.USART3_TX.2.SignalID=NONE
+Dma.USART3_TX.2.SyncEnable=DISABLE
+Dma.USART3_TX.2.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT
+Dma.USART3_TX.2.SyncRequestNumber=1
+Dma.USART3_TX.2.SyncSignalID=NONE
 File.Version=6
 GPIO.groupedBy=Group By Peripherals
@@ -99,4 +137,6 @@
 NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
 NVIC.DMA1_Stream0_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true\:true
+NVIC.DMA1_Stream1_IRQn=true\:0\:0\:false\:false\:true\:true\:false\:true\:true
+NVIC.DMA1_Stream2_IRQn=true\:0\:0\:false\:false\:true\:true\:false\:true\:true
 NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
 NVIC.ForceEnableDMAVector=true
@@ -371,5 +411,5 @@
 STMicroelectronics.X-CUBE-AZRTOS-H7.3.3.0.FileOoSystemJjInterfaces_Checked=true
 STMicroelectronics.X-CUBE-AZRTOS-H7.3.3.0.FileXCcFileOoSystemJjFileXJjCore=true
-STMicroelectronics.X-CUBE-AZRTOS-H7.3.3.0.IPParameters=TX_APP_MEM_POOL_SIZE,FX_APP_MEM_POOL_SIZE,TX_APP_GENERATE_INIT_CODE,TX_APP_CREATION,TX_ENABLE_STACK_CHECKING,TX_NO_FILEX_POINTER,TX_LOW_POWER,FX_ENABLE_EXFAT,FX_ENABLE_FAULT_TOLERANT,FX_FAULT_TOLERANT,FX_FAULT_TOLERANT_DATA,FX_DRIVER_SD_INIT,TX_TIMER_TICKS_PER_SECOND,ThreadXCcRTOSJjThreadXJjCore,ThreadXCcRTOSJjThreadXJjLowOoPowerOosupport,FileXCcFileOoSystemJjFileXJjCore,InterfacesCcFileOoSystemJjFileXOoSDOointerface
+STMicroelectronics.X-CUBE-AZRTOS-H7.3.3.0.IPParameters=TX_APP_MEM_POOL_SIZE,FX_APP_MEM_POOL_SIZE,TX_APP_GENERATE_INIT_CODE,TX_APP_CREATION,TX_ENABLE_STACK_CHECKING,TX_NO_FILEX_POINTER,TX_LOW_POWER,FX_ENABLE_EXFAT,FX_ENABLE_FAULT_TOLERANT,FX_FAULT_TOLERANT,FX_FAULT_TOLERANT_DATA,FX_DRIVER_SD_INIT,TX_TIMER_TICKS_PER_SECOND,ThreadXCcRTOSJjThreadXJjCore,ThreadXCcRTOSJjThreadXJjLowOoPowerOosupport,FileXCcFileOoSystemJjFileXJjCore,InterfacesCcFileOoSystemJjFileXOoSDOointerface,TX_APP_MSG_QUEUE_CREATION,TX_MSG_QUEUE_NAME,TX_NB_MSG
 STMicroelectronics.X-CUBE-AZRTOS-H7.3.3.0.InterfacesCcFileOoSystemJjFileXOoSDOointerface=true
 STMicroelectronics.X-CUBE-AZRTOS-H7.3.3.0.RTOSJjThreadX_Checked=true
@@ -377,6 +417,9 @@
 STMicroelectronics.X-CUBE-AZRTOS-H7.3.3.0.TX_APP_GENERATE_INIT_CODE=false
 STMicroelectronics.X-CUBE-AZRTOS-H7.3.3.0.TX_APP_MEM_POOL_SIZE=8192
+STMicroelectronics.X-CUBE-AZRTOS-H7.3.3.0.TX_APP_MSG_QUEUE_CREATION=1
 STMicroelectronics.X-CUBE-AZRTOS-H7.3.3.0.TX_ENABLE_STACK_CHECKING=1
 STMicroelectronics.X-CUBE-AZRTOS-H7.3.3.0.TX_LOW_POWER=1
+STMicroelectronics.X-CUBE-AZRTOS-H7.3.3.0.TX_MSG_QUEUE_NAME=gsm queue
+STMicroelectronics.X-CUBE-AZRTOS-H7.3.3.0.TX_NB_MSG=512
 STMicroelectronics.X-CUBE-AZRTOS-H7.3.3.0.TX_NO_FILEX_POINTER=1
 STMicroelectronics.X-CUBE-AZRTOS-H7.3.3.0.TX_TIMER_TICKS_PER_SECOND=1000
