
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);
}
}
}