2023-09-18 11:18 PM
Hi all.
I'm transmitting data over the UART from a ToF sensor board (BDC-AFBR-S50 TOF Sensor (mikroe.com)).
I'm currently connecting the UART to both a serial to usb adapter (Adafruit FTDI232), and UART2 on the STM which is running the following code:
#include "main.h"
#include "dma.h"
#include "usart.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
/* USER CODE END Includes */
/* USER CODE BEGIN PTD */
#define BUFFER_SIZE 50
/* USER CODE END PTD */
extern DMA_HandleTypeDef hdma_usart2_rx;
extern UART_HandleTypeDef huart1;
uint8_t rxBuffer[BUFFER_SIZE] = {0};
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* USER CODE BEGIN 0 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
HAL_UART_Transmit(&huart2, rxBuffer, BUFFER_SIZE, 100);
HAL_UART_Receive_DMA(&huart2, rxBuffer, BUFFER_SIZE);
}
/* USER CODE END 0 */
int main(void)
{
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
HAL_UART_Receive_DMA(&huart2, rxBuffer, BUFFER_SIZE);
while (1)
{
}
}
Other initialisations:
huart2.Instance = USART2;
huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
GPIO_InitStruct.Pin = USART_TX_Pin|USART_RX_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USART2 DMA Init */
/* USART2_RX Init */
hdma_usart2_rx.Instance = DMA1_Channel6;
hdma_usart2_rx.Init.Request = DMA_REQUEST_2;
hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart2_rx.Init.Mode = DMA_CIRCULAR;
hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_usart2_rx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(uartHandle,hdmarx,hdma_usart2_rx);
HAL_NVIC_SetPriority(DMA1_Channel6_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel6_IRQn);
You can see in the image that the same data isn't getting picked up by the STM.
I'm certain there's something wrong with my setup, I'm just not experienced enough to figure it out.
Any help would be appreciated :)
2023-09-19 05:28 AM
It's unclear what you are expecting to happen here. Why do you have 2 ports open when your code only interfaces with one?
2023-09-19 07:45 PM
I'm splitting the output from the sensor board and passing it to a serial to usb adapter, and my STM - all three share a common ground.
The two ports open are just to validate that data is being sent through correctly.
My expectation is that the data that is being passed into the STM will be received and transmitted onto the virtual COM port.
2023-09-19 08:16 PM - edited 2023-09-19 08:17 PM
Would recommend breaking it into steps.
Do a HAL_UART_Transmit at the start on a known message to ensure it shows up in COM6. Does it work? If so, that part is validated. (And if not, fix it before proceeding.)
Use a blocking HAL_UART_Receive call to try to receive data. Does any get through? If so, that validates reception. (And if not, fix it before proceeding.)
Then move on to HAL_UART_Receive_DMA. Put a breakpoint in the callback. Does it ever get called? If not, pause program, examine relevant UART and DMA registers, particularly for overflow or DMA error flags. Note that it won't get called until 50 characters are sent. Examine buffer to see if any characters at all made it.
2023-09-22 02:55 PM
You have "extern UART_HandleTypeDef huart1;" but the rest of your code refers to huart2. That won't work unless you have extern in a header file which you currently don't show any header code.
Never call a function, especially a blocking function inside an interrupt. Set a flag and check the flag in you main while loop.
#include "main.h"
#include "dma.h"
#include "usart.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
/* USER CODE END Includes */
/* USER CODE BEGIN PTD */
#define BUFFER_SIZE 50
/* USER CODE END PTD */
extern DMA_HandleTypeDef hdma_usart2_rx;
extern UART_HandleTypeDef huart1; // typo?
extern UART_HandleTypeDef huart2; // should be huart2
uint8_t rxBuffer[BUFFER_SIZE] = {0};
bool dataRdy = false;
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* USER CODE BEGIN 0 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart.Instance == huart2.Instance)
{
dataRdy = true;
HAL_UART_Receive_DMA(&huart2, rxBuffer, BUFFER_SIZE);
}
}
/* USER CODE END 0 */
int main(void)
{
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
HAL_UART_Receive_DMA(&huart2, rxBuffer, BUFFER_SIZE);
while (1)
{
if(dataRdy)
{
dataRdy = false;
HAL_UART_Transmit(&huart2, rxBuffer, BUFFER_SIZE, 100);
}
}
}