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

sd_app_evt_wait cause uart not work.

Hi, I use nrf52832's uart with a simple driver, not "nrf_drv_uart", because I don't know how to use receive and transmit interruption with "nrf_drv_uart". the uart drive i used is bellow:

void drv_uart_init(void)

 init_io();
 init_uart();
}

static void init_io(void)

 nrf_gpio_cfg_output(UART_TX);
 nrf_gpio_pin_set(UART_TX);
 nrf_gpio_cfg_input( UART_RX,NRF_GPIO_PIN_PULLUP);
}

static void init_uart(void)
{
 NRF_UART0->BAUDRATE = DEFAULT_BAUD;
 
 NRF_UART0->PSELTXD = UART_TX;
 NRF_UART0->PSELRXD = UART_RX;
 
 enable_interrupt();
 // ????
 NRF_UART0->ENABLE = UART_ENABLE_ENABLE_Enabled;
 NRF_UART0->TASKS_STARTTX = 1;
 NRF_UART0->TASKS_STARTRX = 1;
}

static void enable_interrupt(void)
{
 NRF_UART0->EVENTS_RXDRDY = 0;  
 NRF_UART0->INTENSET = (UART_INTENSET_RXDRDY_Enabled << UART_INTENSET_RXDRDY_Pos)|(UART_INTENSET_TXDRDY_Enabled << UART_INTENSET_TXDRDY_Pos);
 
 NVIC_SetPriority(UART0_IRQn, 7);
    NVIC_ClearPendingIRQ(UART0_IRQn);
    NVIC_EnableIRQ(UART0_IRQn);
}

void UARTE0_UART0_IRQHandler(void)
{
 if(NRF_UART0->EVENTS_RXDRDY==1)
 {
  NRF_UART0->EVENTS_RXDRDY = 0;
  *m_p_rx_buf=NRF_UART0->RXD;
  m_p_rx_buf++;
  *m_p_rx_len=*m_p_rx_len+1;
 }
 if(NRF_UART0->EVENTS_TXDRDY==1)
 {
  NRF_UART0->EVENTS_TXDRDY = 0;
  if(m_tx_len>0)
  {
   NRF_UART0->TXD = *m_p_tx_buf;
   m_p_tx_buf++;
   m_tx_len=m_tx_len-1;
  }
 }
}

In the idle hook function, I call nrf_pwr_mgmt_run(), as follows:

void vApplicationIdleHook( void )
{
  nrf_pwr_mgmt_run();
}

when I remove "nrf_pwr_mgmt_run();", or remove "ret_code_t ret_code = sd_app_evt_wait();" in the nrf_pwr_mgmt_run function, the uart can work correctly,  I can receive all data on my computer, but when i use "nrf_pwr_mgmt_run" or "sd_app_evt_wait", the uart cannot work, i receive no data on my computer.

why?

Parents
  • You made me read twice to see the function vApplicationIdleHook and figure out that you are using FreeRTOS. 

    Well the simple uart needs CPU to be awake to trigger send/receive as you are not using EasyDMA to push pop data from the UART FIFO to/from the RAM.

    In which context are you transmitting data? when you make the chip go to sleep, are you expecting the data transfer to be triggered in some other interrupt context?

  • My needs are very simple,  i trigger the data(100 byte) transfer in a cycle task , the cycle is 5s,  implemented by a APP_TIMER (FreeRTOS), after i trigger the first byte data transfer, i want the chip go to sleep , and then i hope the uart can transfer the rest of bytes. also, in the sleep mode, i want the uart can receive data and notify the cpu to get the received data, not query the flag "NRF_UART0->EVENTS_RXDRDY" periodically. the "nrf_drv_uart" or  UART FIFO can realize my needs?

  • tianbing357 said:
    the "nrf_drv_uart" or  UART FIFO can realize my needs?

     Well using a simple_uart should be good enough for the simple use case you are using.

    If you are using APP_Timer to trigger the transfer and the UARTE0_UART0_IRQHandler makes sure to read the UART FIFO and push it to RAM, then adding the sleep in vApplicationIdleHook should work just fine without a problem. Why not just use Tickless IDLE mode and let the RTOS take care of the sleep? All you need to do is set 

    #define configUSE_TICKLESS_IDLE 1

    and leave vApplicationIdleHook function empty.

    You will get better power optimization with this as compared to vApplicationIdleHook sleep, since in tickless modethe RTC tick interrupt is disabled until the expected wake time.

Reply
  • tianbing357 said:
    the "nrf_drv_uart" or  UART FIFO can realize my needs?

     Well using a simple_uart should be good enough for the simple use case you are using.

    If you are using APP_Timer to trigger the transfer and the UARTE0_UART0_IRQHandler makes sure to read the UART FIFO and push it to RAM, then adding the sleep in vApplicationIdleHook should work just fine without a problem. Why not just use Tickless IDLE mode and let the RTOS take care of the sleep? All you need to do is set 

    #define configUSE_TICKLESS_IDLE 1

    and leave vApplicationIdleHook function empty.

    You will get better power optimization with this as compared to vApplicationIdleHook sleep, since in tickless modethe RTC tick interrupt is disabled until the expected wake time.

Children
No Data
Related