Getting USART instance from HardwareSerial?

Post here first, or if you can't find a relevant section!
Post Reply
MGeo
Posts: 38
Joined: Thu Dec 19, 2019 10:29 am
Answers: 2

Getting USART instance from HardwareSerial?

Post 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() {
 
}
by MGeo » Sat Feb 27, 2021 9:41 am
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
Go to full post
User avatar
fpiSTM
Posts: 1738
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 91
Location: Le Mans
Contact:

Re: Getting USART instance from HardwareSerial?

Post 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*/
}
MGeo
Posts: 38
Joined: Thu Dec 19, 2019 10:29 am
Answers: 2

Re: Getting USART instance from HardwareSerial?

Post 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
Post Reply

Return to “General discussion”