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

Sleep between bytes on nRF52832 UART

Hi, I am a bit confused about power consumption when using app_uart_fifo. To save power I put MCU to sleep in between each sent and received byte by using __WFE and __SEV instructions. This helps but not as much as I expected. Code snippets are from receive mechanism but I get same behaviour when sending. As seen in picture 1 and 2 (attachmentsleeep_between_bytes.PNG) the current goes down between receiving each byte but the current peaks are much wider than the time it takes to receive each byte. I use GPIO:s to measure the time for handling the APP_UART_DATA_READY event in the event handler (picture 3, ~150ns) and the time it takes until app_uart_get() has executed (picture 4, ~5µs,). Baud rate is 115 200 and SDK version is 13.0.0. If I increase baud rate to 460 800 I can’t see any current dips at all between received bytes. I also tried another approach in which I stored received bytes in a temporary buffer directly from the event handler but the result was similar. So is this what I can expect with nRF52 or should it be possible to decrease the width of the current peaks with a more efficient implementation?

void uart_event_handler(app_uart_evt_t * p_event)
{
   if (p_event->evt_type == APP_UART_TX_EMPTY)
   {
      tx_empty_flag = true;
   }
   else if (p_event->evt_type == APP_UART_DATA_READY)
   {
      nrf_gpio_pin_set(ARDUINO_0_PIN);
      nrf_gpio_pin_set(ARDUINO_2_PIN);
      data_ready_flag = true;
      nrf_gpio_pin_clear(ARDUINO_2_PIN);;
   }
}

static void sleep_until_byte_received(uint8_t * byte)
{
   __WFE();
   __SEV();
   __WFE();

   if( true == data_ready_flag )
   {
      while (app_uart_get(byte) != NRF_SUCCESS);
   }
   nrf_gpio_pin_clear(ARDUINO_0_PIN);;
}

void receive_msg(msg_type_t * msg_type, uint8_t * seq_nr, uint16_t * msg_len, uint8_t * msg_buffer, bool * crc_err)
{
   .
   .
   .
   /* get data bytes */
   if( *msg_type == REQ_FROM_KEY || *msg_type == RSP_FROM_CYL)
   {
     for (uint16_t x = 0; x < rx_data_len; x++)
     {
         sleep_until_byte_received(&received_byte);
         *(msg_buffer + x) = received_byte;
         receive_buffer[HDR_LEN + x] = received_byte;
         received_byte = 0;
     }
   }
   .
   .
   .
} 

BR Mattias

Related