2022-08-04 07:54 AM
I am trying to transfer sensor data collected on a NUCLEO-144 L552ZET6Q board to a Sparkfun Artemis BLE Module via UART DMA. However, I can't get the STM32 to send anything on any UART besides messages to TeraTerm using the basic HAL_UART_TRANSMIT function on LPUART1.
I've tried using a logic analyzer, and it's showing absolutely no response from the UART, and the debugger in STM32CubeIDE is showing an error code of 0x200001f8, which I can't match to any combination of errors so far.
I'm pretty new to STM32Cube, so it's likely that I'm missing something in the setup, though I haven't been able to find what it is so far. Anyone see anything that I've missed so far?
Below is a few pieces of a basic program to count the number of UART transfers from the STM32 to the Artemis BLE. The Artemis is then meant to write that count to a BLE Characteristic to be read on a BLE Scanning app like BLE Scanner or nRF Connect.
int main(void)
{
/* USER CODE BEGIN 1 */
uint8_t cnt = 0;
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_ADC1_Init();
MX_LPUART1_UART_Init();
MX_RTC_Init();
MX_UCPD1_Init();
MX_USART2_UART_Init();
MX_USB_PCD_Init();
/* USER CODE BEGIN 2 */
uint8_t tx_buf[64] = "";
uint8_t len = 0;
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
cnt++;
len = sprintf(tx_buf, "Transmissions sent: %d\r\n", cnt);
if(HAL_UART_Transmit_DMA(&huart2,tx_buf,sizeof(tx_buf)) != HAL_OK)
{
Error_Handler();
}
HAL_Delay(500);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
static void MX_USART2_UART_Init(void)
{
/* USER CODE BEGIN USART2_Init 0 */
/* USER CODE END USART2_Init 0 */
/* USER CODE BEGIN USART2_Init 1 */
/* USER CODE END USART2_Init 1 */
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;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart2.Init.ClockPrescaler = UART_PRESCALER_DIV1;
huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_SetTxFifoThreshold(&huart2, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_SetRxFifoThreshold(&huart2, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_DisableFifoMode(&huart2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART2_Init 2 */
/* USER CODE END USART2_Init 2 */
}
static void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMAMUX1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
/* DMA1_Channel1_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
}
Feel free to let me know what other information might be helpful
2022-08-04 08:44 AM
Check cube nucleo 2 boards uart examples. Not a plug and play, just a first thing to help find the root cause. Make sure the uart pins are not the ones wired to the builtin stlink virtual com port...
2022-08-04 09:04 AM
I tried that and things went haywire in CubeIDE. I'll take another look though.
*update as I was working on this: Progress! I'm seeing the latter half of the first transmission being sent to BLE! It looks like this on my end: "ssions sent: 1". And this is with HAL_UART_Transmit_DMA! Unfortunately, it encounters an error after the first transfer.
Does this ring a bell to anyone?
2022-08-04 09:07 AM
Yeah, trying to search the example you suggest crashed CubeIDE... Anywhere else I can find it?
2022-08-04 11:08 PM
If in the cube nucleo example projects you are lucky to have richer uart example with cyclic buffers, start from these ones. On my side, i use LL because with console like protocol, block length is known last and usually 1Mbps hardly justify a DMA like a 12 Mbps SPI would do, unless using the dma to have time periodic checks without interrupts.
2022-08-05 07:25 AM
May not be your issue, but...
if(HAL_UART_Transmit_DMA(&huart2,tx_buf,sizeof(tx_buf)) != HAL_OK)
That line will ALWAYS send 64 bytes (the size of tx_buf[]). The additional bytes will be NULL chars (i.e. zeros). I don't know if that will confuse your other device. Use strlen(tx_buf), or "len" instead of sizeof().
Not related to your problem, but something to improve your future code:
len = sprintf(tx_buf, "Transmissions sent: %d\r\n", cnt);
Get in the habit of using snprintf() instead of sprintf(). Yeah, in this particular case you can be sure you won't overflow tx_buf. But in bigger programs that may not be as clear. Or someone may change the buffer size trying to save a few bytes of RAM, or add to the format string, or you print integer values that you KNOW will never be > 1000 but some bug corrupts the value and it is suddenly something like 2147483648. snprint() will save you many hours of debugging time.