5 years ago.

Redefine Serial UART tx pin

Hi,

For a SDI-12 protocol, I need to control TX pin in order to provide a pulse before sending actual command, that is used to wake-up the sensors.

I tried to setup a DigitalOut on TX pin, but it seems that the already configured Serial stops working.

Also tried to use HAL driver to switch between Normal and Alternate function, without success.

I am working with proprietary hardware, based on STM32L433 processor.

The Serial is a member of a class named SDI12_HalfDuplex , and is created in the constructor as in this:

class SDI12_HalfDuplex 
{
public:
    SDI12_HalfDuplex(PinName tx, PinName rx);

    void SDI12_HalfDuplex::SendBreak();
 .... other members functions;

private:
    Serial      mUART;
};

in the implementation, I have:

SDI12_HalfDuplex::SDI12_HalfDuplex(PinName tx, PinName rx) :  mUART(tx, rx) {}

void SDI12_HalfDuplex::SendBreak()
{
    DigitalOut tx(SDI_TX);
    tx = 0;
    wait_ms(15);
    tx = 1;
    wait_ms(10);

// WHAT TO DO HERE in order to have mUART working again ???

   return;
}

This doesn't work as mUART becomes unusable after redefining tx as digital output.

Using a dummy sending of a null byte, makes the SDI-12 interface work, but not with all sensor types as the minimum break time is not achieved.

Any help will be much appreciated.

BR, Carlos Paiva

1 Answer

5 years ago.

You could try changing the TX pin pull up/down mode instead of completely reassigning output function. You should effectively be able to generate a simple pulse by switching between output mode to pulldown and then to pullup mode. Serial peripheral uses pins in pullup mode by default so line rests at 3.3V. I have used this to turn the tx, rx pins off while leaving the uart peripheral initialized. Requires only single function call to change pin state. And probably requires this extra include.

#include #include "hal/pinmap.h"

pin_mode(SDI_TX, OpenDrainPullDown);
pin_mode(SDI_TX PullUp);

The possible options defined in PinNamesTypes.h https://github.com/ARMmbed/mbed-os/blob/master/targets/TARGET_STM/PinNamesTypes.h

typedef enum {
    PullNone          = 0,
    PullUp            = 1,
    PullDown          = 2,
    OpenDrainPullUp   = 3,
    OpenDrainNoPull   = 4,
    OpenDrainPullDown = 5,
    PushPullNoPull    = PullNone,
    PushPullPullUp    = PullUp,
    PushPullPullDown  = PullDown,
    OpenDrain         = OpenDrainPullUp,
    PullDefault       = PullNone
} PinMode;

Accepted Answer

Thanks for your reply. This seems a good idea. I will give it a try, and I will come back with results.

posted by Carlos Paiva 29 Mar 2019

Your answer lead me to the proper solution, by only change the mux of alternate function with the following code: <<code>> void SDI12_HalfDuplex::SendBreak() {

GPIO_InitTypeDef stTX;

stTX.Pin = GPIO_PIN_11; stTX.Mode = GPIO_MODE_OUTPUT_PP; stTX.Speed = GPIO_SPEED_LOW; stTX.Pull = GPIO_NOPULL;

HAL_GPIO_Init(GPIOB, &stTX);

GPIOB->ODR &= GPIO_PIN_11; wait_ms(13);

GPIOB->ODR |= GPIO_PIN_11; wait_ms(9);

stTX.Pin = GPIO_PIN_11; stTX.Mode = GPIO_MODE_AF_PP; stTX.Speed = GPIO_SPEED_LOW; stTX.Pull = GPIO_NOPULL; stTX.Alternate = GPIO_AF8_LPUART1;

HAL_GPIO_Init(GPIOB, &stTX);

return; } <<code>>

Thanks for the advice.

posted by Carlos Paiva 04 Apr 2019