Page 1 of 1

Getting USART instance from HardwareSerial?

Posted: Fri Feb 26, 2021 10:34 am
by MGeo
Hi,

I am using an F303K8, and hoping to use the F3's built in USART pin inversion capabilities to avoid extra external hardware inverters.

I have found the LL functions to do this and it works (see minimal sketch below), but it requires me to explicitly define the USART instance (USART1 in this case). This required me to dig through the lower level files to figure out what the USART mapping was for the specific variant.

Is there a better way where I can somehow retrieve the USART instance from HardwareSerial?

Thanks,
George

Code: Select all

#include "stm32yyxx_ll.h"

/* HardwareSerial::HardwareSerial(PinName _rx, PinName _tx) */
HardwareSerial mySerial1(PA_10, PA_9);

void setup()
{

  /* Serial to display the received data */
  mySerial1.begin(115200);

  // Use LL functions to invert F303K8 TX and RX pins
  LL_USART_Disable(USART1);
  LL_USART_SetRXPinLevel(USART1, LL_USART_RXPIN_LEVEL_INVERTED);
  LL_USART_SetTXPinLevel(USART1, LL_USART_TXPIN_LEVEL_INVERTED);
  LL_USART_Enable(USART1);

}

void loop() {
 
}

Re: Getting USART instance from HardwareSerial?

Posted: Fri Feb 26, 2021 12:54 pm
by fpiSTM
You can use this function:

Code: Select all

void *pinmap_peripheral(PinName pin, const PinMap *map)
Like this:

Code: Select all

  /* Determine the U(S)ART peripheral to use (USART1, USART2, ...) */
  USART_TypeDef *uart_tx = pinmap_peripheral(PA_9, PinMap_UART_TX);
  USART_TypeDef *uart_rx = pinmap_peripheral(PA_10, PinMap_UART_RX);
And this one to ensure both has the same peripheral instance:

Code: Select all

USART_TypeDef * instance = pinmap_merge_peripheral(uart_tx, uart_rx);
if (instance  == NP) {
 /*Error*/
}

Re: Getting USART instance from HardwareSerial?

Posted: Sat Feb 27, 2021 9:41 am
by MGeo
Perfect, thanks Frederic.

For anyone finding this thread I found that in C++/ino you need to cast the return pointer to avoid an invalid conversion from 'void*' error (works as is in C).

Code: Select all

#if defined(SBUS_INVERT)

  // derive USART instance from pin definitions
  USART_TypeDef *uart_tx = (USART_TypeDef *)pinmap_peripheral(TX_PIN, PinMap_UART_TX);
  USART_TypeDef *uart_rx = (USART_TypeDef *)pinmap_peripheral(RX_PIN, PinMap_UART_RX);

  // make sure they are the same instance, returns NP if fail
  USART_TypeDef *instance = (USART_TypeDef *)pinmap_merge_peripheral(uart_tx, uart_rx);
  assert_param(instance != NP);

  LL_USART_Disable(instance);
  LL_USART_SetTXPinLevel(instance, LL_USART_TXPIN_LEVEL_INVERTED);
  LL_USART_SetRXPinLevel(instance, LL_USART_RXPIN_LEVEL_INVERTED);
  LL_USART_Enable(instance);

#endif