nRF9160 dk UARTE Baremetal Rx Driver - Unknown Byte Size

Hello,

I am trying to have a minimal bare metal based driver for nrf9160 UARTE with an unknown frame size. 

I assume that ENDRX interrupt is triggered when RXD.MAXCNT bytes are received and RXRDY interrupt is triggered when every byte is received. 

Is there an idle line detect mechanism in nrf9160? I plan to have at least two UARTs in my project with Rx capability.

It would be great if I get a minimal driver / steps or register configuration involved.

Thanks,

Pawan 

  • Hi,

     

    Is there an idle line detect mechanism in nrf9160? I plan to have at least two UARTs in my project with Rx capability.

    Are you thinking about flow control, using CTS/RTS in addition to RXD/TXD? If so, yes, the hardware supports this.

     

    Kind regards,

    Håkon

  • Hello Hakon,

    No, I'm just using the TXD RXD lines. I would like to have an interrupt when the RXD line goes idle after recieving an unknown number of bytes. Is this possible?

    Thanks

    Pawan

  • Hi Pawan,

     

    PawanNordic said:
    No, I'm just using the TXD RXD lines. I would like to have an interrupt when the RXD line goes idle after recieving an unknown number of bytes. Is this possible?

    This isn't a feature that the UARTE peripheral has. This must be added by you, if this is a requirement.

     

    I would recommend that you look into the uart asynchronous API from zephyr, where you can set a timeout on the RX operation.

     

    Kind regards,

    Håkon

  • Hello Hakon,

    I am trying to establish UARTE EVENTS_RXDRDY Interrupt handling on a minimal bare metal firmware and I observe that the ISR is hit only once. Maybe the mcu goes to some fault condition thereafter.

    My simple code:

    void my_Usart2_init(void)
    {
        /* GPIO init */
        nrf_gpio_cfg_default(1);
        nrf_gpio_pin_set(1);
        nrf_gpio_cfg_default(0);
        nrf_gpio_pin_set(0);
    
        NRF_UARTE2->PSEL.TXD = 1;
        NRF_UARTE2->PSEL.RXD = 0;
        NRF_UARTE2->TASKS_STOPTX = 1;
        NRF_UARTE2->TASKS_STOPRX = 1;    
    
        NRF_UARTE2->BAUDRATE = (uint32_t)UARTE_BAUDRATE_BAUDRATE_Baud115200;
    
        /*Initialize DMA*/
        NRF_UARTE2->INTENCLR = 0xffffffffUL;
        NRF_UARTE2->INTENSET =
            (UARTE_INTEN_ENDTX_Enabled << UARTE_INTEN_ENDTX_Pos) |
            (UARTE_INTEN_RXDRDY_Enabled << UARTE_INTEN_RXDRDY_Pos) |
            (UARTE_INTEN_ERROR_Enabled << UARTE_INTEN_ERROR_Pos);
    
        /* APP IRQ */
        Sys_clearFastAppIrq(UARTE2_SPIM1_SPIS1_TWIM1_TWIS1_IRQn);
        Sys_enableFastAppIrq(UARTE2_SPIM1_SPIS1_TWIM1_TWIS1_IRQn,
                             APP_LIB_SYSTEM_IRQ_PRIO_HI,
                             UARTE2_IRQHandler);
        NRF_UARTE2->ENABLE = UARTE_ENABLE_ENABLE_Enabled;
    
    }
    
    volatile uint8_t datahere;
    void __attribute__((__interrupt__)) UARTE2_IRQHandler(void)
    {
        if(NRF_UARTE2.instance->EVENTS_RXDRDY != 0)
        {   
            NRF_UARTE2.instance->EVENTS_RXDRDY = 0;
            (NRF_UARTE2.instance->RXD.PTR) = (uint32_t)&datahere;
            NRF_UARTE2.instance->TASKS_STARTRX = 1;
        }
    }

    I need some expert help or a register level simple example on UARTE Rx please.

    Thanks,

    Pawan

Related