dynamic pinctrl

.overlay:

// Com with PC
&uart0 {
    status = "okay";
    current-speed = <115200>;
};

// Com with Virtial sensor
&uart1 {
    status = "okay";
    pinctrl-0 = <&uart1_tx>;
    pinctrl-1 = <&uart1_rx>;
    pinctrl-names = "default", "alternate";
};

// Define RX and TX
&pinctrl {

    uart1_tx: uart1_tx {

        group1 {
            psels = <NRF_PSEL(UART_TX, 0, 7)>,
                    <NRF_PSEL(UART_RX, 0, 6)>;
        };
        /*group2 {
            psels = <NRF_PSEL(UART_RX, 0, 6)>;
        };*/
    };

    uart1_rx: uart1_rx {
    
        group1 {
            psels = <NRF_PSEL(UART_TX, 0, 6)>,
                    <NRF_PSEL(UART_RX, 0, 7)>;
            bias-pull-up;
        };
        /*group2 {
            psels = <NRF_PSEL(UART_TX, 0, 6)>;
        };*/
    };
};

main:

#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/drivers/uart.h>
#include <zephyr/device.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/pm/device.h>
#include <zephyr/drivers/pinctrl.h>


// Retrieving nodes
#define UART1_NL DT_NODELABEL(uart1)


// Macros
#define MAX_DATA_LENGTH 512


// Commands
#define get_address "0!"
#define start_measure "0M!"
#define get_measure "0D0!"


// Init LOG
LOG_MODULE_REGISTER(main, LOG_LEVEL_DBG);


// Defining devices
static const struct device *dev_uart1 = DEVICE_DT_GET(UART1_NL);


// Parameters for data storage
uint8_t buffer[MAX_DATA_LENGTH];
size_t i = 0;


// Baudrate manipulation function and parameters
struct uart_config cfg;


// Switch between tx and rx
static const struct pinctrl_dev_config *pinctrl_config;


void init_pinctrl_config(void)
{

    pinctrl_config = pinctrl_lookup_config(dev_uart1);
    if (!pinctrl_config) {
        LOG_ERR("Failed to get pinctrl config");
    }
}


void switch_to_tx(void) {

        pinctrl_apply_state(pinctrl_config, 0);
        LOG_DBG("Switched to transmit pin state");
}

void switch_to_rx(void) {

        pinctrl_apply_state(pinctrl_config, 1);
        LOG_DBG("Switched to receive pin state");
}


// Callback uart1
static void cb_uart1(const struct device *d, void *user_data) {

        uint8_t byte;

        while (uart_irq_update(d) && uart_irq_rx_ready(d)) {

                while (uart_fifo_read(d, &byte, 1)) {

                        if (byte == '\0') {

                                buffer[i] = '\0';

                                LOG_INF("Message: %s", buffer);

                                LOG_HEXDUMP_DBG(buffer, MAX_DATA_LENGTH, "Hexdump: ");
                                
                                i = 0;
                                memset(buffer, 0, MAX_DATA_LENGTH);

                        // Data contains bad bytes randomly placed in the message, these have to filtered out
                        } else if ((i < MAX_DATA_LENGTH - 1) && (byte != '\r') && (byte != '\0') && (byte !='\n')) {

                                buffer[i++] = byte;

                        } else if (i >= MAX_DATA_LENGTH - 1) {

                                LOG_WRN("Buffer overflow for data buffer");
                                i = 0;
                                memset(buffer, 0, MAX_DATA_LENGTH);
                        }
                }
        }
}


// Send command

void send_command(const char *buf) {

        uart_irq_rx_disable(dev_uart1);
        switch_to_tx();
        uart_tx_enable(dev_uart1);

        while (*buf) {

                uart_poll_out(dev_uart1, *buf++);
        }

        uart_tx_disable(dev_uart1);
        switch_to_rx();
        uart_irq_rx_enable(dev_uart1);
}


// Main
int main(void)
{

        if (uart_config_get(dev_uart1, &cfg) != 0) {
                LOG_ERR("Failed to retrieve config for uart1");
                return 1;
        }

        cfg.baudrate = 1200;
        cfg.parity = UART_CFG_PARITY_EVEN;
        cfg.stop_bits = UART_CFG_STOP_BITS_1;
        cfg.data_bits = UART_CFG_DATA_BITS_7;
        cfg.flow_ctrl = UART_CFG_FLOW_CTRL_NONE;
        
        if (uart_configure(dev_uart1, &cfg) != 0) {
                LOG_ERR("Failed to configure initial baudrate for uart1");
                return 1;
        }
        LOG_DBG("Uart1 baudrate set to 1200");


        // Check if uart1 is ready
        if(!device_is_ready(dev_uart1)) {
                LOG_WRN("Uart1 is not ready");
                return 1;
        }
        LOG_DBG("Uart1 is ready");


        // Link callback and enable interrupt request for uart1
        if (uart_irq_callback_user_data_set(dev_uart1, cb_uart1, NULL) != 0) {
                LOG_ERR("Failed to set UART1 callback");
        } else {
                LOG_DBG("Callback for UART1 set");
        }


        // init pinctrl
        init_pinctrl_config();

        
        // Let sensor initialize
        switch_to_rx();
        uart_irq_rx_enable(dev_uart1);
        k_sleep(K_MSEC(1000));


        // Check address
        send_command(get_address);
        k_sleep(K_MSEC(1000));


        // Start measurement
        send_command(start_measure);
        k_sleep(K_MSEC(2000));


        // Get measurement
        send_command(get_measure);


        // Run forever
        while (1) {

                k_sleep(K_FOREVER);
        }

        return 0;
}

Parents Reply Children
No Data
Related