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

i2c and nrf52832

Hello!

I want to connect the MCP9808 with the nrf52832. Therefor I use i2C. My example on the nrf52832 is the:

<nRF5_SDK_v11_0_0 folder>\examples\ble_peripheral\experimental_ble_app_eddystone\

Now, I have written the code of the twi_sensor example in the eddystone example.

When I debug the program, the function err_code = nrf_drv_twi_rx(&m_twi_mcp9808, TEMP_ADDR, (uint8_t*)&m_sample, sizeof(m_sample)); in the void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context) writes C1 in the MSB_Data and FF in the LSB_Data of the m_sample irrespective of the temperature.

Have I forgotten something in the program code.

My whole code:

/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
 *
 * The information contained herein is property of Nordic Semiconductor ASA.
 * Terms and conditions of usage are described in detail in NORDIC
 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
 *
 * Licensees are granted free, non-transferable use of the information. NO
 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
 * the file.
 *
 */

/** @file
 *
 * @defgroup experimental_ble_sdk_app_eddystone_main main.c
 * @{
 * @ingroup experimental_ble_sdk_app_eddystone
 * @brief Eddystone Beacon UID Transmitter sample application main file.
 *
 * This file contains the source code for an Eddystone beacon transmitter sample application.
 */

#include <stdbool.h>
#include <stdint.h>
#include "ble_advdata.h"
#include "nordic_common.h"
#include "softdevice_handler.h"
#include "bsp.h"
#include "app_timer.h"
#include "nrf_temp.h" //XXX Neu


// XXX YYY Neu
#include "boards.h"
#include "app_util_platform.h"
#include "app_error.h"
#include "nrf_drv_twi.h"
#include "nrf_delay.h"

/*Pins to connect shield. */
#define DEVICE_SCL_PIN 0
#define DEVICE_SDA_PIN 1

/*Common addresses definition for accelereomter. */
#define TEMP_ADDR        (0x18U)

#define TEMP_REG_RFU   	 0x00U
#define TEMP_REG_CONFIG  0x01U
#define TEMP_REG_TUPPER  0x02U
#define TEMP_REG_TLOWER  0x03U
#define TEMP_REG_TCRIT   0x04U
#define TEMP_REG_TEMP	   0x05U
#define TEMP_REG_MID	   0x06U
#define TEMP_REG_DID	   0x07U
#define TEMP_REG_RESR    0x08U


// [max 255, otherwise "int16_t" won't be sufficient to hold the sum
//  of accelerometer samples]
#define NUMBER_OF_SAMPLES 20

// XXX YYY Neu



#define IS_SRVC_CHANGED_CHARACT_PRESENT 0                                 /**< Include the service changed characteristic. If not enabled, the server's database cannot be changed for the lifetime of the device. */

#define CENTRAL_LINK_COUNT              0                                 /**< Number of central links used by the application. When changing this number remember to adjust the RAM settings*/
#define PERIPHERAL_LINK_COUNT           0                                 /**< Number of peripheral links used by the application. When changing this number remember to adjust the RAM settings*/

#define APP_CFG_NON_CONN_ADV_TIMEOUT    0                                 /**< Time for which the device must be advertising in non-connectable mode (in seconds). 0 disables the time-out. */
#define NON_CONNECTABLE_ADV_INTERVAL    MSEC_TO_UNITS(1000, UNIT_0_625_MS) /**< The advertising interval for non-connectable advertisement (100 ms). This value can vary between 100 ms and 10.24 s). */

// Eddystone common data
#define APP_EDDYSTONE_UUID              0xFEAA                            /**< UUID for Eddystone beacons according to specification. */
#define APP_EDDYSTONE_RSSI              0xEE                              /**< 0xEE = -18 dB is the approximate signal strength at 0 m. */

// Eddystone UID data
#define APP_EDDYSTONE_UID_FRAME_TYPE    0x00                              /**< UID frame type is fixed at 0x00. */
#define APP_EDDYSTONE_UID_RFU           0x00, 0x00                        /**< Reserved for future use according to specification. */
#define APP_EDDYSTONE_UID_ID            0x01, 0x02, 0x03, 0x04, \
                                        0x05, 0x06                        /**< Mock values for 6-byte Eddystone UID ID instance.  */
#define APP_EDDYSTONE_UID_NAMESPACE     0xAA, 0xAA, 0xBB, 0xBB, \
                                        0xCC, 0xCC, 0xDD, 0xDD, \
                                        0xEE, 0xEE                        /**< Mock values for 10-byte Eddystone UID ID namespace. */

// Eddystone URL data
#define APP_EDDYSTONE_URL_FRAME_TYPE    0x10                              /**< URL Frame type is fixed at 0x10. */
#define APP_EDDYSTONE_URL_SCHEME        0x00                              /**< 0x00 = "http://www" URL prefix scheme according to specification. */
#define APP_EDDYSTONE_URL_URL           0x6e, 0x6f, 0x72, 0x64, \
                                        0x69, 0x63, 0x73, 0x65, \
                                        0x6d,0x69, 0x00                   /**< "nordicsemi.com". Last byte suffix 0x00 = ".com" according to specification. */
// Eddystone TLM data
#define APP_EDDYSTONE_TLM_FRAME_TYPE    0x20                              /**< TLM frame type is fixed at 0x20. */
#define APP_EDDYSTONE_TLM_VERSION       0x00                              /**< TLM version might change in the future to accommodate other data according to specification. */
#define APP_EDDYSTONE_TLM_BATTERY       0x00, 0xF0                        /**< Mock value. Battery voltage in 1 mV per bit. */
#define APP_EDDYSTONE_TLM_TEMPERATURE   0x0F, 0x00                        /**< Mock value. Temperature [C]. Signed 8.8 fixed-point notation. */
#define APP_EDDYSTONE_TLM_ADV_COUNT     0x00, 0x00, 0x00, 0x03            /**< Running count of advertisements of all types since power-up or reboot. */
#define APP_EDDYSTONE_TLM_SEC_COUNT     0x00, 0x00, 0x00, 0x04            /**< Running count in 0.1 s resolution since power-up or reboot. */

#define DEAD_BEEF                       0xDEADBEEF                        /**< Value used as error code on stack dump, can be used to identify stack location on stack unwind. */

#define APP_TIMER_PRESCALER             0                                 /**< Value of the RTC1 PRESCALER register. */
#define APP_TIMER_OP_QUEUE_SIZE         4                                 /**< Size of timer operation queues. */

static ble_gap_adv_params_t m_adv_params;                                 /**< Parameters to be passed to the stack when starting advertising. */

// XXX Neu

//static uint8_t eddystone_url_data[] =   /**< Information advertised by the Eddystone URL frame type. */
//{
//    APP_EDDYSTONE_URL_FRAME_TYPE,   // Eddystone URL frame type.
//    APP_EDDYSTONE_RSSI,             // RSSI value at 0 m.
//    APP_EDDYSTONE_URL_SCHEME,       // Scheme or prefix for URL ("http", "http://www", etc.)
//    APP_EDDYSTONE_URL_URL           // URL with a maximum length of 17 bytes. Last byte is suffix (".com", ".org", etc.)
//};

/** @snippet [Eddystone UID data] */
//static uint8_t eddystone_uid_data[] =   /**< Information advertised by the Eddystone UID frame type. */
//{
//    APP_EDDYSTONE_UID_FRAME_TYPE,   // Eddystone UID frame type.
//    APP_EDDYSTONE_RSSI,             // RSSI value at 0 m.
//    APP_EDDYSTONE_UID_NAMESPACE,    // 10-byte namespace value. Similar to Beacon Major.
//    APP_EDDYSTONE_UID_ID,           // 6-byte ID value. Similar to Beacon Minor.
//    APP_EDDYSTONE_UID_RFU           // Reserved for future use.
//};
/** @snippet [Eddystone UID data] */

// XXX Neu

static uint8_t eddystone_tlm_data[] =   /**< Information advertised by the Eddystone TLM frame type. */
{
    APP_EDDYSTONE_TLM_FRAME_TYPE,   // Eddystone TLM frame type.
    APP_EDDYSTONE_TLM_VERSION,      // Eddystone TLM version.
    APP_EDDYSTONE_TLM_BATTERY,      // Battery voltage in mV/bit.
    APP_EDDYSTONE_TLM_TEMPERATURE,  // Temperature [C].
    APP_EDDYSTONE_TLM_ADV_COUNT,    // Number of advertisements since power-up or reboot.
    APP_EDDYSTONE_TLM_SEC_COUNT     // Time since power-up or reboot. 0.1 s increments.
};



// XXX YYY Neu


typedef struct
{
		uint8_t MSB_Data;
		uint8_t LSB_Data;
	
} sample_t;

sample_t Temp_Sensor;

/* Buffer for samples. */
static sample_t m_sample_buffer[NUMBER_OF_SAMPLES] = {0};

/* Indicates if reading operation from accelerometer has ended. */
static volatile bool m_xfer_done = true;
/* Indicates if setting mode operation has ended. */
static volatile bool m_set_mode_done = false;
/* TWI instance. */
static const nrf_drv_twi_t m_twi_mcp9808 = NRF_DRV_TWI_INSTANCE(0);










// XXX YYY Neu


/**@brief Callback function for 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]   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(DEAD_BEEF, line_num, p_file_name);
}

/**@brief Function for initializing the advertising functionality.
 *
 * @details Encodes the required advertising data and passes it to the stack.
 *          Also builds a structure to be passed to the stack when starting advertising.
 */
static void advertising_init(void)
{
    uint32_t      err_code;
		int32_t				temp;
		uint8_t 			temp_a;
		uint8_t 			temp_b;
    ble_advdata_t advdata;
    uint8_t       flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
    ble_uuid_t    adv_uuids[] = {{APP_EDDYSTONE_UUID, BLE_UUID_TYPE_BLE}};

    uint8_array_t eddystone_data_array;                             // Array for Service Data structure.
/** @snippet [Eddystone data array] */
		 	
		
		// XXX Neu
		sd_temp_get(&temp);
		
		temp_a = temp; 
		temp_b = temp;
		temp_a >>= 2;
		temp_b <<= 6;


		
		eddystone_tlm_data [4] = temp_a;
		eddystone_tlm_data [5] = temp_b; 
		
    eddystone_data_array.p_data = (uint8_t *) eddystone_tlm_data;   // Pointer to the data to advertise.
    eddystone_data_array.size = sizeof(eddystone_tlm_data);         // Size of the data to advertise.
/** @snippet [Eddystone data array] */

    ble_advdata_service_data_t service_data;                        // Structure to hold Service Data.
    service_data.service_uuid = APP_EDDYSTONE_UUID;                 // Eddystone UUID to allow discoverability on iOS devices.
    service_data.data = eddystone_data_array;                       // Array for service advertisement data.

    // Build and set advertising data.
    memset(&advdata, 0, sizeof(advdata));

    advdata.name_type               = BLE_ADVDATA_NO_NAME;
    advdata.flags                   = flags;
    advdata.uuids_complete.uuid_cnt = sizeof(adv_uuids) / sizeof(adv_uuids[0]);
    advdata.uuids_complete.p_uuids  = adv_uuids;
    advdata.p_service_data_array    = &service_data;                // Pointer to Service Data structure.
    advdata.service_data_count      = 1;

    err_code = ble_advdata_set(&advdata, NULL);
    APP_ERROR_CHECK(err_code);

    // Initialize advertising parameters (used when starting advertising).
    memset(&m_adv_params, 0, sizeof(m_adv_params));

    m_adv_params.type        = BLE_GAP_ADV_TYPE_ADV_NONCONN_IND;
    m_adv_params.p_peer_addr = NULL;                                // Undirected advertisement.
    m_adv_params.fp          = BLE_GAP_ADV_FP_ANY;
    m_adv_params.interval    = NON_CONNECTABLE_ADV_INTERVAL;
    m_adv_params.timeout     = APP_CFG_NON_CONN_ADV_TIMEOUT;
}


/**@brief Function for starting advertising.
 */
static void advertising_start(void)
{
    uint32_t err_code;

    err_code = sd_ble_gap_adv_start(&m_adv_params);
    APP_ERROR_CHECK(err_code);

    err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING);
    APP_ERROR_CHECK(err_code);
}


/**@brief Function for initializing the BLE stack.
 *
 * @details Initializes the SoftDevice and the BLE event interrupt.
 */
static void ble_stack_init(void)
{
    uint32_t err_code;
    
// XXX Neu	
// see nrf_sdm.h for more details
nrf_clock_lf_cfg_t clock_lf_cfg = 
{
    .source = NRF_CLOCK_LF_SRC_RC,
    .rc_ctiv = 16, // Interval in 0.25 s, 16 * 0.25 = 4 sec
    .rc_temp_ctiv = 2, // Check temperature every .rc_ctiv, but calibrate every .rc_temp_ctiv 
    .xtal_accuracy = NRF_CLOCK_LF_XTAL_ACCURACY_250_PPM,
};
    
    // Initialize the SoftDevice handler module.
    SOFTDEVICE_HANDLER_INIT(&clock_lf_cfg, NULL);
    
    ble_enable_params_t ble_enable_params;
    err_code = softdevice_enable_get_default_config(CENTRAL_LINK_COUNT,
                                                    PERIPHERAL_LINK_COUNT,
                                                    &ble_enable_params);
    APP_ERROR_CHECK(err_code);
    
    //Check the ram settings against the used number of links
    CHECK_RAM_START_ADDR(CENTRAL_LINK_COUNT,PERIPHERAL_LINK_COUNT);
    
    // Enable BLE stack.
    err_code = softdevice_enable(&ble_enable_params);
    APP_ERROR_CHECK(err_code);
}


/**@brief Function for doing power management.
 */
static void power_manage(void)
{
    uint32_t err_code = sd_app_evt_wait();
    APP_ERROR_CHECK(err_code);
}






/**
 * @brief Function XXX YYY Neu for i2c.
 */

/**
 * @brief Function for setting active mode on mcp9808.
 */
void mcp9808_set_mode(void)
{
    ret_code_t err_code;
    uint8_t reg[1] = {TEMP_REG_TEMP};

    err_code = nrf_drv_twi_tx(&m_twi_mcp9808, TEMP_ADDR, reg, sizeof(reg), false);  
    APP_ERROR_CHECK(err_code);
    
    while(m_set_mode_done == false);
}


/**
 * @brief TWI events handler.
 */
void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
{   
    ret_code_t err_code;
    static sample_t m_sample;
    
    switch(p_event->type)
    {
        case NRF_DRV_TWI_EVT_DONE:
            if ((p_event->type == NRF_DRV_TWI_EVT_DONE) &&
                (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_TX))
            {
                if(m_set_mode_done != true)
                {
                    m_set_mode_done  = true;
                    return;
                }
                m_xfer_done = false;
                /* Read 4 bytes from the specified address. */
                err_code = nrf_drv_twi_rx(&m_twi_mcp9808, TEMP_ADDR, (uint8_t*)&m_sample, sizeof(m_sample));
                APP_ERROR_CHECK(err_code);
            }
            else
            {
                Temp_Sensor = m_sample;
                m_xfer_done = true;
            }
            break;
        default:
            break;        
    }   
}


void twi_init (void)
{
    ret_code_t err_code;
    
    const nrf_drv_twi_config_t twi_mcp9808_config = {
			.scl                = DEVICE_SCL_PIN,
       .sda                = DEVICE_SDA_PIN,
       .frequency          = NRF_TWI_FREQ_100K,
       .interrupt_priority = APP_IRQ_PRIORITY_HIGH
    };
    
    err_code = nrf_drv_twi_init(&m_twi_mcp9808, &twi_mcp9808_config, twi_handler, NULL);
    APP_ERROR_CHECK(err_code);
    
    nrf_drv_twi_enable(&m_twi_mcp9808);
}










// XXX YYY Neu










/**
 * @brief Function for application main entry.
 */
int main(void)
{
    uint32_t err_code;
		uint32_t pin = 2;
		nrf_gpio_cfg_output(pin);
		nrf_gpio_pin_set(pin);
    // Initialize.
    APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, false);
    err_code = bsp_init(BSP_INIT_LED, APP_TIMER_TICKS(100, APP_TIMER_PRESCALER), NULL);
 //  	err_code = 0x0; //XXX Neu
		APP_ERROR_CHECK(err_code);
    ble_stack_init();
    advertising_init();
    twi_init();
	  mcp9808_set_mode(); 	
//    LEDS_ON(LEDS_MASK);
    // Start execution.
    advertising_start();



	  uint8_t reg = TEMP_REG_TEMP;
    ret_code_t err_code_sens;
	
    // Enter main loop.
    for (;; )
    {
        nrf_delay_ms(100);
    /* Start transaction with a slave with the specified address. */
        do
        {
            __WFE();
        }while(m_xfer_done == false);
        err_code_sens = nrf_drv_twi_tx(&m_twi_mcp9808, TEMP_ADDR, &reg, sizeof(reg), true);
        APP_ERROR_CHECK(err_code_sens);
        m_xfer_done = false;
				
        power_manage();
				advertising_init();	//XXX Neu
    }
}


/**
 * @}
 */

Thanks!

Parents Reply Children
No Data
Related