This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

UART configuration and manipulation

In order to interact with the UART, you need to first declare a device struct and then get a binding to the device:

static struct device *uart;
...
uart = device_get_binding("UART_1");

Then in order to switch the UART on and off you need to do:

uart_off()
{
    NRF_UARTE1_NS->TASKS_STOPTX = 1;
    NRF_UARTE1_NS->TASKS_STOPRX = 1;

    NRF_UARTE1_NS->ENABLE = 0;
}

uart_on()
{
    NRF_UARTE1_NS->ENABLE = 8;
    
    NRF_UARTE1_NS->TASKS_STARTRX = 1;
    NRF_UARTE1_NS->TASKS_STARTTX = 1;
}

But I wonder if there is a way to write a function that will take as input a string like "UART_1" and will perform the power on and off of the specified device.

What I have found out so far is that you can write a function like this:

void uart_power_on(NRF_UARTE_Type* dev)
{
    dev->ENABLE = 8;
    dev->TASKS_STARTRX = 1;
    dev->TASKS_STARTTX = 1;
}

And use as argument for UART1 for example NRF_UARTE1_NS.

In this way I can power on the device again. But what I would like to do is initialize the device and power it on or off in one function with the same argument.

Any ideas?

  • This is definitely possible to use and it is my last resort, but there is definitely a matching mechanism between the string and the NRF_UARTE_Type*

  • Ok, so what I am trying to do is read data from UARTx, using a callback. In order to do that, I need a struct device *uart.

    This can be handled in the struct that I mentioned previously, this struct can be given all 'struct device's you need and the function can handle what one it wants.

    Then I need to initialize that device, using the device_get_binding("UART_X").

    Init your UARTs seperately, the init stage is independant of the actual manipulation of the UART. No need to have a function that inits, reads and turns them ON/OFF.

    Then I need to attach a callback to that device to treat incoming data: uart_irq_callback_set(uart, callback)

    ISRs set-ups should be done in your init function for the UART, this is another thing that only ever is one once and does not need to be in a recallable function. The custom struct I mentioned can also hold the 'struct gpio_callback' variables.

    Then I need to be able to switch on and off this uart. As you have suggested in your answer, you need to do this:

    Set-up a single method to decide what UART you are looking to control, as mentioned previously a typedef such as:

    typedef enum
    {
    	UART0,
    	UART1,
    	UART2
    }UARTS;

    Would allow you to call a function in this manner: uart_power_on(UART0).

    All together you would call a function with your struct and enum as uart_power_on(&MyStruct, UART0).

    From here, your functions should be able to decypher your input, pull all the variables and information it needs from your struct and global defines and then perform the operation required.

    If you really really want to condense the function, you could look at then calling void uart_power_on(NRF_UARTE_Type* dev) inside this function which can call the specific version of NRF_UARTE#_NS but that's a bit overkill unless you are really stuck for application memory size.

Related