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

UART TX pin pulls down during reset

DSLogic output

On the picture channel 2 connected to reset button on PDK.

UART channel drops to GND 4ms after button pressed.

How to prevent this? 

Tried this: https://devzone.nordicsemi.com/f/nordic-q-a/25591/uart-hits-communication-error/100873#100873

no changes.

Code works fine with external board (STM32) until reset or full hardware power down and power on causes pull-down.

  • nRF52840-Preview_DK(PCA10056) 0.9.3
  • Segger Embedded Studio.
  • Code based on UART example
  • RTT enabled

#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "app_uart.h"
#include "app_error.h"
#include "nrf_delay.h"
#include "nrf.h"
#include "bsp.h"
#include "protocol.h"
#include "app_timer.h"
#include "nordic_common.h"
#include "nrf_error.h"
#include "nrf_drv_clock.h"

//logging
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"

#include "nrf_uart.h"


#define MAX_TEST_DATA_BYTES     (15U)                /**< max number of test bytes to be used for tx and rx. */
#define UART_TX_BUF_SIZE 64                         /**< UART TX buffer size. */
#define UART_RX_BUF_SIZE 16                         /**< UART RX buffer size. */


#define rcvd_max_data_len 12
static ConfPack cmd;

static uint8_t index = 0;
static uint8_t err_count = 0;

APP_TIMER_DEF(m_singleshot_timer_on);     /* Handler for repeated timer used to send on cmd throught uart. */
APP_TIMER_DEF(m_singleshot_timer_off);   /* Handler for repeated timer used to send off cmd throught uart. */


//Function starting the internal LFCLK oscillator.
static void lfclk_request(void)
{
    ret_code_t err_code = nrf_drv_clock_init();
    APP_ERROR_CHECK(err_code);
    nrf_drv_clock_lfclk_request(NULL);
}


#define CRC32_POLY   0x04C11DB7

uint32_t STM_crc_32_update(uint32_t crc, uint32_t data)
{
    crc = crc ^ data;
    for(uint32_t i=0;i<32;i++)
        if (crc & 0x80000000)
            crc = (crc << 1) ^ CRC32_POLY;
        else
            crc = (crc << 1);
    return(crc);
}


uint32_t crc32_4byte( uint32_t *buf, int len)
{
    uint32_t v;
    uint32_t crc;
    crc = 0xFFFFFFFF;
    while(len >= 4) {
        v = (*buf++);
        crc = STM_crc_32_update(crc,v);
        len-=4;
    }
    
    return crc;
}

void uart_event_handle(app_uart_evt_t * p_event)
{
    static uint8_t data_array[rcvd_max_data_len];
    uint32_t       err_code;

    switch (p_event->evt_type)
    {
        case APP_UART_DATA_READY:
            /*
            app_timer_stop(m_singleshot_timer_id);
            app_timer_start(m_singleshot_timer_id, APP_TIMER_TICKS(50), NULL);
            */
            //timer restart
            err_code = app_uart_get(&data_array[index]);
            APP_ERROR_CHECK(err_code);
            index++;    
                if (index = 12) //received full length packet
                {   
                    StatPack spack;
                    uint32_t crc;
                    memcpy((void*)&spack,data_array,sizeof(StatPack));
                    crc = crc32_4byte((uint32_t*)data_array,sizeof(StatPack));
                    if((spack.rep.slave_stat&VER_MASK) == FW_VERSION<<8)   //header check
                    {
                      if (crc == 0)                       //CRC check
                      {
                          bsp_board_led_invert(1);
                          //==manage data==
                          /*
                          =spack.rep.current;
                          =spack.rep.rpm;
                          =spack.rep.slave_stat;
                          =spack.rep.voltage;
                          */

                        //flushes
                        index = 0;
                        err_count = 0;
                      }else{
                        //move data 1 byte left
                        for(int j=0; j<(rcvd_max_data_len-1); j++){
                          data_array[j]=data_array[j+1];
                        }
                        index--;//CRC check will be repeted
                        err_count++;
                      }
                    } else { //case version error! err_count++;
                      bsp_board_led_invert(2);
                      for(int j=0; j<(rcvd_max_data_len-1); j++){
                        data_array[j]=data_array[j+1];
                      }
                      index--;//CRC check will be repeted
                      err_count++;
                    }
                }else if(index > 12){
                   bsp_board_led_on(3);//How it happens on power off?
                   index = 0;
                
                }else if(err_count > 12){
                   app_uart_flush();//buffers flush                  
                   //flushes
                        index = 0;
                        err_count = 0;
                   bsp_board_led_invert(3);
                }  
            break;

        /*case APP_UART_COMMUNICATION_ERROR:
            APP_ERROR_HANDLER(p_event->data.error_communication);
            break;
        */
        case APP_UART_FIFO_ERROR:
            APP_ERROR_HANDLER(p_event->data.error_code);          
            break;

        default:
            break;
    }
}

static void timer_on_handler(void * p_context){
  
  bsp_board_led_on(0);
  
  uint32_t err_code;
  cmd.conf.dgain=0;
  cmd.conf.igain=0;
  cmd.conf.linstep=0;
  cmd.conf.oc_current=2000;
  cmd.conf.pgain=8;
  cmd.conf.rpm_set=5000;
  cmd.conf.uv_voltage=10000;
  
    cmd.conf.master_stat = (1<<8);
    cmd.conf.master_stat |= MVER;
    cmd.conf.master_stat |= SET_OCUV;
    cmd.conf.master_stat &= ~SET_PID_K;
    cmd.conf.master_stat &= ~SET_PID;
    cmd.conf.master_stat |= SET_RPM_MOD;
    cmd.conf.master_stat &= ~RUN_CAL;
  
  cmd.crc=crc32_4byte((uint32_t*)&cmd.conf,sizeof(cmd.conf)); 
  
  uint8_t cmd_send_buf[sizeof(cmd)];
  memcpy((void*)&cmd_send_buf, &cmd, sizeof(cmd));

  for (int i=0;i<sizeof(cmd);i++){
    while (app_uart_put(cmd_send_buf[i]) != NRF_SUCCESS);
  }
}

static void timer_off_handler(void * p_context){
  bsp_board_led_off(0);
  uint32_t err_code;
  cmd.conf.dgain=0;
  cmd.conf.igain=0;
  cmd.conf.linstep=0;
  cmd.conf.oc_current=2000;
  cmd.conf.pgain=8;
  cmd.conf.rpm_set=0;
  cmd.conf.uv_voltage=10000;
  
    cmd.conf.master_stat = (1<<8);
    cmd.conf.master_stat |= MVER;
    cmd.conf.master_stat |= SET_OCUV;
    cmd.conf.master_stat &= ~SET_PID_K;
    cmd.conf.master_stat &= ~SET_PID;
    cmd.conf.master_stat |= SET_RPM_MOD;
    cmd.conf.master_stat &= ~RUN_CAL;
  
  cmd.crc=crc32_4byte((uint32_t*)&cmd.conf,sizeof(cmd.conf));
  
  uint8_t cmd_send_buf[sizeof(cmd)];
  memcpy((void*)&cmd_send_buf, &cmd, sizeof(cmd));
  
  for (int i=0;i<sizeof(cmd);i++){
    while (app_uart_put(cmd_send_buf[i]) != NRF_SUCCESS);
  }  
}


static void create_timers()
{
    ret_code_t err_code = app_timer_init();
    APP_ERROR_CHECK(err_code);
    
    err_code = app_timer_create(&m_singleshot_timer_on, APP_TIMER_MODE_SINGLE_SHOT, timer_on_handler);
    APP_ERROR_CHECK(err_code);
    
    err_code = app_timer_create(&m_singleshot_timer_off, APP_TIMER_MODE_SINGLE_SHOT, timer_off_handler);
    APP_ERROR_CHECK(err_code);
}

void motor_on(){
  bsp_board_led_on(0);
  
  uint32_t err_code;
  cmd.conf.dgain=0;
  cmd.conf.igain=0;
  cmd.conf.linstep=0;
  cmd.conf.oc_current=2000;
  cmd.conf.pgain=8;
  cmd.conf.rpm_set=5000;
  cmd.conf.uv_voltage=10000;
  
    cmd.conf.master_stat = (1<<8);
    cmd.conf.master_stat |= MVER;
    cmd.conf.master_stat |= SET_OCUV;
    cmd.conf.master_stat &= ~SET_PID_K;
    cmd.conf.master_stat &= ~SET_PID;
    cmd.conf.master_stat |= SET_RPM_MOD;
    cmd.conf.master_stat &= ~RUN_CAL;
  
  cmd.crc=crc32_4byte((uint32_t*)&cmd.conf,sizeof(cmd.conf)); 
  
  uint8_t cmd_send_buf[sizeof(cmd)];
  memcpy((void*)&cmd_send_buf, &cmd, sizeof(cmd));

  for (int i=0;i<sizeof(cmd);i++){
    while (app_uart_put(cmd_send_buf[i]) != NRF_SUCCESS);
  }
}

void motor_off(){
  bsp_board_led_off(0);
  uint32_t err_code;
  cmd.conf.dgain=0;
  cmd.conf.igain=0;
  cmd.conf.linstep=0;
  cmd.conf.oc_current=2000;
  cmd.conf.pgain=8;
  cmd.conf.rpm_set=0;
  cmd.conf.uv_voltage=10000;
  
    cmd.conf.master_stat = (1<<8);
    cmd.conf.master_stat |= MVER;
    cmd.conf.master_stat |= SET_OCUV;
    cmd.conf.master_stat &= ~SET_PID_K;
    cmd.conf.master_stat &= ~SET_PID;
    cmd.conf.master_stat |= SET_RPM_MOD;
    cmd.conf.master_stat &= ~RUN_CAL;
  
  cmd.crc=crc32_4byte((uint32_t*)&cmd.conf,sizeof(cmd.conf));
  
  uint8_t cmd_send_buf[sizeof(cmd)];
  memcpy((void*)&cmd_send_buf, &cmd, sizeof(cmd));
  
  for (int i=0;i<sizeof(cmd);i++){
    while (app_uart_put(cmd_send_buf[i]) != NRF_SUCCESS);
  }
}

int main(void)
{   
    /* Initializing Log */
    ret_code_t err_code = NRF_LOG_INIT(NULL);
    APP_ERROR_CHECK(err_code);

    NRF_LOG_DEFAULT_BACKENDS_INIT();    
    
    NRF_LOG_INFO("HEY FROM NRF LOG!!!");

    bsp_board_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS);

    const app_uart_comm_params_t comm_params =
      {
          RX_PIN_NUMBER,  
          TX_PIN_NUMBER,  
          RTS_PIN_NUMBER,
          CTS_PIN_NUMBER,
          APP_UART_FLOW_CONTROL_DISABLED,
          false,
          NRF_UART_BAUDRATE_115200
      };

    APP_UART_FIFO_INIT(&comm_params,
                         UART_RX_BUF_SIZE,
                         UART_TX_BUF_SIZE,
                         uart_event_handle,
                         APP_IRQ_PRIORITY_LOWEST,
                         err_code);

    APP_ERROR_CHECK(err_code);
 
    
    //Timer
    lfclk_request();
    create_timers();
    
    nrf_delay_ms(500);
    while(1){
      if(bsp_board_button_state_get(BSP_BOARD_BUTTON_0)){
        err_code = app_timer_start(m_singleshot_timer_on, APP_TIMER_TICKS(100), NULL);
        APP_ERROR_CHECK(err_code);
      }
      if(bsp_board_button_state_get(BSP_BOARD_BUTTON_1)){
        err_code = app_timer_start(m_singleshot_timer_off, APP_TIMER_TICKS(100), NULL);
        APP_ERROR_CHECK(err_code);
      }
      
    }
 }

Parents Reply Children
  • Hello,

    The nRF52840 Preview-DK is no longer supported or recommended to develop on, it contains early engineering samples with missing features, issues and not production tested. You should get a nRF52840 DK with the production grade samples on as soon as possible (the PDK have not been available for quite some time, so just order an nRF52840 DK from a Nordic distributor and you should get a DK).

    In general I recommend pulling the nRESET pin low directly if you want to measure timing, in this case pull P0.18 directly to ground:
    https://infocenter.nordicsemi.com/topic/ps_nrf52840/pin.html?cp=3_0_0_6_0 

    All that said, during (pin) reset there is no guaranteed operation/behaviour. If you want to do a hardware pin reset you would only need to pull it low for >0.2us to ensure a proper reset.

    Best regards,
    Kenneth

Related