Choose the UARTE API (Async/interrupt driven) during runtime

Hello,

I need a way to decide on which Api to use for UARTE (configured as uart1) once in main(). I am not intending to switch between them nor to use them at the same time. I am aware that it is not possible to use both simultaneously on the same uart. I am using the the nRF52840 with the following configuration

/ {
    chosen {
        zephyr,console = &uart0;
    };
};


&uart0 {
    compatible = "nordic,nrf-uart";
    current-speed = <115200>;
    status = "okay";
    pinctrl-0 = <&uart0_default_alt>;
    pinctrl-1 = <&uart0_sleep_alt>;
    pinctrl-names = "default", "sleep";
};


&uart1 {
    compatible = "nordic,nrf-uarte";
    current-speed = <115200>;
    status = "okay";
    pinctrl-0 = <&uart1_default_alt>;
    pinctrl-1 = <&uart1_sleep_alt>;
    pinctrl-names = "default", "sleep";
    
    /* Used for communication on modbus sensor */
    test_dev: modbus0 {
		compatible = "zephyr,modbus-serial";
		status = "okay";
	};
};

  • Uart0 is chosen for the console debugging.
  • Uart1 needs to work using
    • the interrupt driven api if the sensor is of type x
    • and work with the async api if the sensor is of type y.

Any help, even a hacky workaround, will be much appreciated. 

  • Hi,

    Which sensor you are talking about? and how is that connected to the board?

    Once you know if the sensor is present (or which type of sensor is present) then you can do the conditional compilation

    (Look at devicetree constructs that would allow you to get information from the compiled devicetree of the board)

    for example, you can get the node identifier of active node of certain type (compatible) using DT_COMPAT_GET_ANY_STATUS_OKAY()

  • Let me clarify your questions: 

    I am not talking about the built-in types of sensors in zephyr (like temperature sensor or so), but I mean my own types of sensors or let's say, my own implemented applications (e.g. a current sensor / voltage sensor, etc.)

     The thing is: I do not know the type of sensor at compilation time. I do know it at boot up based on some pin states, e.g.

    • if pin P0.14 is pulled low externally, then the sensor type is voltage sensor -> and I then want to use interrupt driven API and the corresponding callbacks I implemented. That would be the lower part (modbus subnode) of uart1 in the device overlay 
    • if pin P0.14 is pulled high externally, then the sensor type is current sensor -> and I then want to use async API and the corresponding callbacks I implemented. That would be the upper part (main uart1 node) in the device overlay 

    I hope this makes my requirements clear. 

    Further clarifications: 

    • the current sensor is a custom made pcb with nRF52840 that reads out data over modbus (uart1 subnode, async api) from an external device.
    • the voltage sensor is a custom made pcb with nRF52840 that uses its own adc to sense voltage and send its values through serial (main uart1 node, interrupt driven api) 

    Note: building two separate firmware application (with the corresponding configs) is unfortunately not an option.

  • Hi,

    Thank you for the clarification.

    I think for such a requirement you would need to update the driver (both zephyr and your device drivers) to allow you to assess the pin voltage at boot time and then use one of the api accordingly.

    Regards,
    Naeem

Related