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

I2C communication between nrf52 and stm32

Hi all,

I am currently building I2C communication between nrf52832 and a stm32 chip, stm32 as the master and nrf52 as the slave.

The situation is the stm32 couldn't get the data from the nrf52 but I can actually the data flowing through the SDA channel via the oscilloscope.

When I change the slave to another sensor with I2C, the stm32 can receive the data from the sensor so I guess my stm32 code is good and the problem might be in the code of the nrf52.

But another weird thing is, when I use the arduino as the master and nrf52 as the slave, the arduino can receive the data from the nrf52.

I really have no idea what is wrong. Any suggestion would help.

Thanks in advance,

Duncan

Here is code for the nrf52 and the image from the oscilloscope.

#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "nordic_common.h"
#include "nrf_sdh.h"
#include "nrf_sdh_ble.h"
#include "app_timer.h"
#include "bsp_btn_ble.h"
#include "ble.h"
#include "ble_hci.h"
#include "ble_advdata.h"
#include "ble_advertising.h"
#include "ble_conn_params.h"
#include "ble_db_discovery.h"
#include "ble_lbs_c.h"
#include "ble_conn_state.h"
#include "nrf_ble_gatt.h"
#include "nrf_pwr_mgmt.h"
#include <ble_types.h>
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
#include "nrfx_twis.h"  //header file for twis
#include "nrf_drv_twis.h"

#define APP_BLE_CONN_CFG_TAG      1                                     /**< A tag that refers to the BLE stack configuration we set with @ref sd_ble_cfg_set. Default tag is @ref APP_BLE_CONN_CFG_TAG. */
#define APP_BLE_OBSERVER_PRIO     3                                     /**< Application's BLE observer priority. You shouldn't need to modify this value. */

#define SCAN_INTERVAL             0x0100                                /**< Determines scan interval in units of 0.625 millisecond. */
#define SCAN_WINDOW               0x0050                                /**< Determines scan window in units of 0.625 millisecond. */
#define SCAN_DURATION             0x0000                                /**< Duration of the scanning in units of 10 milliseconds. If set to 0x0000, scanning will continue until it is explicitly disabled. */

#define target_uuid               0xAA10    // the 16 bit uuid of the target device, or the 12 and 13 octetcs of the 128 bit uuid(be careful to the order)
#define NRF_LOG_ENABLED           1
#define NRF_LOG_DEFAULT_LEVEL     3

/* TWI instance ID. */
#define TWIS_INST_ID         0

#define MASTER_ADDR0         0x29
#define MASTER_ADDR1         0
#define NRFX_TWIS_DEFAULT_CONFIG_SCL_PULL  0
#define NRFX_TWIS_DEFAULT_CONFIG_SDA_PULL  0


const uint8_t peer_address[6]  = {0x00,0x78,0xB9,0X48,0XB4,0XB0};

static int8_t m_rssi;                      //the varible used to store the signal strenth from the advertising report of the target device


//static char const m_target_periph_name[] = "Beacon";       /**< Name of the device we try to connect to.*/

static uint8_t m_scan_buffer_data[BLE_GAP_SCAN_BUFFER_MIN]; /**< buffer where advertising reports will be stored by the SoftDevice. */

/**@brief Pointer to the buffer where advertising reports will be stored by the SoftDevice. */
static ble_data_t m_scan_buffer =
{
    m_scan_buffer_data,
    BLE_GAP_SCAN_BUFFER_MIN
};

/**@brief Scan parameters requested for scanning and connection. */
static ble_gap_scan_params_t const m_scan_params =
{
    .active   = 0,
    .interval = SCAN_INTERVAL,
    .window   = SCAN_WINDOW,

    .timeout           = SCAN_DURATION,
    .scan_phys         = BLE_GAP_PHY_1MBPS,
    .filter_policy     = BLE_GAP_SCAN_FP_ACCEPT_ALL,

};



/* TWIS instance. */
static const nrfx_twis_t m_twis = NRFX_TWIS_INSTANCE(TWIS_INST_ID);

/* Buffer for samples would be sent. */
const int8_t *m_data_buffer=&m_rssi;
int8_t received_value;




/**@brief Function to handle asserts in the SoftDevice.
 *
 * @details This function will be called in case of an assert in the SoftDevice.
 *
 * @warning This handler is an example only and does not fit a final product. You need to analyze
 *          how your product is supposed to react in case of Assert.
 * @warning On assert from the SoftDevice, the system can only recover on reset.
 *
 * @param[in] line_num     Line number of the failing ASSERT call.
 * @param[in] p_file_name  File name of the failing ASSERT call.
 */
void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name)
{
    app_error_handler(0xDEADBEEF, line_num, p_file_name);
}


/**
 * @brief TWIS events handler.
 */
void twis_handler(nrfx_twis_evt_t const * p_event)
{
    switch (p_event->type)
    {
    //if get a reading request from the master
    case NRFX_TWIS_EVT_READ_REQ:
       if(p_event->data.buf_req) 
       {
            nrfx_twis_tx_prepare(&m_twis,m_data_buffer, sizeof(m_data_buffer));
            NRF_LOG_INFO("TWIS get data transfer request.\n");    
       }
       break;
   //once the reading is succfully done, clear the data buffer
   case NRFX_TWIS_EVT_READ_DONE:
        //memset(m_data_buffer, 0x00, sizeof(m_data_buffer));
        NRF_LOG_INFO("TWIS data transfer done.\n");
       break;
	  case NRFX_TWIS_EVT_WRITE_REQ:
			
       if(p_event->data.buf_req) {
           nrfx_twis_rx_prepare(&m_twis, &received_value, sizeof(&received_value));
       }		   
       break;
   case NRFX_TWIS_EVT_WRITE_DONE:
      break;	 
    default:
       break;
    }
}

/**
 * @brief twis initialization.
 */
void twis_init (void)
{
    ret_code_t err_code;

    const nrfx_twis_config_t m_twis_config = {
       .addr               = {MASTER_ADDR0, MASTER_ADDR1},
       .scl                = 27,
       .sda                = 26,
       .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
    };

    err_code = nrfx_twis_init(&m_twis, &m_twis_config, twis_handler);
    APP_ERROR_CHECK(err_code);

    nrfx_twis_enable(&m_twis);
    NRF_LOG_INFO("TWIS initiation success.\n");
}


/**@brief Function to start scanning. */
static void scan_start(void)
{
    ret_code_t ret;

    (void) sd_ble_gap_scan_stop();

    //NRF_LOG_INFO("Start scanning for device name %s.", (uint32_t)m_target_periph_name);
    ret = sd_ble_gap_scan_start(&m_scan_params, &m_scan_buffer);
    APP_ERROR_CHECK(ret);
}

/**@brief Function for handling the advertising report BLE event.
 *
 * @param[in] p_adv_report  Advertising report from the SoftDevice.
 */
static void on_adv_report(ble_gap_evt_adv_report_t const * p_adv_report)
{

    uint8_t j=0;   //variable for printing out the peer address from the advertising report of our target device 
  uint8_t p_peer_address[6];
  ret_code_t err_code;

    
    
    //print out the peer address of the target device
    while (j<6)
  {
    p_peer_address[j]=p_adv_report->peer_addr.addr[j];
      j++;
  }

    // searching the device uuid, only works when the target uuid is specified as the type 0x02
    // we can use other feature to do the matching, like device name, manufature specified data, peer address...... 
    if (peer_address[0]==p_peer_address[0]&&
      peer_address[1]==p_peer_address[1]&&
      peer_address[2]==p_peer_address[2]&&
      peer_address[3]==p_peer_address[3]&&
      peer_address[4]==p_peer_address[4]&&
      peer_address[5]==p_peer_address[5])
    {
      m_rssi = p_adv_report->rssi;//taking the rssi value
      NRF_LOG_INFO("my_RSSI: %d",m_rssi);
    }

     err_code = sd_ble_gap_scan_start(NULL, &m_scan_buffer);
     APP_ERROR_CHECK(err_code);
}


/**@brief Function for handling BLE events.
 *
 * @param[in]   p_ble_evt   Bluetooth stack event.
 * @param[in]   p_context   Unused.
 */
static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
{
    //ret_code_t err_code;

    // For readability.
    ble_gap_evt_t const * p_gap_evt = &p_ble_evt->evt.gap_evt;

    switch (p_ble_evt->header.evt_id)
    {
        //once receive the advertising report, implement the report handler
        //potential changed: directly receive RSSI report might be more sensitive
        case BLE_GAP_EVT_ADV_REPORT:
            on_adv_report(&p_gap_evt->params.adv_report);
            break;
    
        default:
            // No implementation needed.
            break;
    }
}

/**@brief Function for initializing the BLE stack.
 *
 * @details Initializes the SoftDevice and the BLE event interrupts.
 */
static void ble_stack_init(void)
{
    ret_code_t err_code;

    err_code = nrf_sdh_enable_request();
    APP_ERROR_CHECK(err_code);

    // Configure the BLE stack using the default settings.
    // Fetch the start address of the application RAM.
    uint32_t ram_start = 0;
    err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
    APP_ERROR_CHECK(err_code);

    // Enable BLE stack.
    err_code = nrf_sdh_ble_enable(&ram_start);
    APP_ERROR_CHECK(err_code);

    // Register a handler for BLE events.
    NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
}


/**@brief Function for initializing power management.
 */
static void power_management_init(void)
{
    ret_code_t err_code;
    err_code = nrf_pwr_mgmt_init();
    APP_ERROR_CHECK(err_code);
}


/**@brief Function for handling the idle state (main loop).
 *
 * @details Handle any pending log operation(s), then sleep until the next event occurs.
 */
static void idle_state_handle(void)
{
    if (NRF_LOG_PROCESS() == false)
    {
        nrf_pwr_mgmt_run();
    }
}


/** @brief Function for initializing the log module.
 */
static void log_init(void)
{
    ret_code_t err_code = NRF_LOG_INIT(NULL);
    APP_ERROR_CHECK(err_code);

    NRF_LOG_DEFAULT_BACKENDS_INIT();
}



int main(void)
{
    // Initialize.
    log_init();
    power_management_init();
    ble_stack_init();
    ble_conn_state_init();
    twis_init();

    // Start execution.
    NRF_LOG_INFO("BLE and I2C started.");
    scan_start();

    for (;;)
    {
        idle_state_handle();
    }
}

From the oscilloscope, I can see the stm32 sent the start condition, stop condition, the slave address, the write or read command; the nrf52 sent the ACK to appropriate positions and data.   

Parents Reply Children
No Data
Related