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

nRF52832 with BMX055

Hello everyone!

I'm using this board: https://item.taobao.com/item.htm?spm=a230r.1.14.16.f3db6e4e1De39A&id=560311112293&ns=1&abbucket=7#detail

It's configured 4-wire SPI follow this table 

I can't read data out of BMX055. Can everyone help me!. I using SDK 11, Softdevice s132_nrf52_2.0.0. 

Parents Reply Children
  • Oh sorry, following your question

    I read value by RX and it is -127. I tried to change value of CS pin but it did not work

    - value is -127 and never change

    - I don't know how to check error codes (I'm newbie :( )

    - yes, i did. But can't find anything

    - No

    This is my code 

    #include <stdint.h>
    #include <string.h>
    #include "nordic_common.h"
    #include "nrf.h"
    #include "ble_hci.h"
    #include "ble_advdata.h"
    #include "ble_advertising.h"
    #include "ble_conn_params.h"
    #include "softdevice_handler.h"
    #include "app_timer.h"
    #include "app_button.h"
    #include "ble_nus.h"
    #include "app_uart.h"
    #include "app_util_platform.h"
    #include "bsp.h"
    #include "bsp_btn_ble.h"
    #include "nrf_delay.h"
    #include "nrf_drv_spi.h"
    #include "bma2x2.h"
    #include "bma2x2.h"
    #include "bmg160.h"
    #include "bmm150.h"
    #include "bmm150_defs.h"
    
    #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 1 /**< Number of peripheral links used by the application. When changing this number remember to adjust the RAM settings*/
    
    #define DEVICE_NAME "nRF52832_BMX055" /**< Name of device. Will be included in the advertising data. */
    #define NUS_SERVICE_UUID_TYPE BLE_UUID_TYPE_VENDOR_BEGIN /**< UUID type for the Nordic UART Service (vendor specific). */
    
    #define APP_ADV_INTERVAL 64 /**< The advertising interval (in units of 0.625 ms. This value corresponds to 40 ms). */
    #define APP_ADV_TIMEOUT_IN_SECONDS 180 /**< The advertising timeout (in units of seconds). */
    
    #define APP_TIMER_PRESCALER 0 /**< Value of the RTC1 PRESCALER register. */
    #define APP_TIMER_OP_QUEUE_SIZE 4 /**< Size of timer operation queues. */
    
    #define MIN_CONN_INTERVAL MSEC_TO_UNITS(20, UNIT_1_25_MS) /**< Minimum acceptable connection interval (20 ms), Connection interval uses 1.25 ms units. */
    #define MAX_CONN_INTERVAL MSEC_TO_UNITS(75, UNIT_1_25_MS) /**< Maximum acceptable connection interval (75 ms), Connection interval uses 1.25 ms units. */
    #define SLAVE_LATENCY 0 /**< Slave latency. */
    #define CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS) /**< Connection supervisory timeout (4 seconds), Supervision Timeout uses 10 ms units. */
    #define FIRST_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(5000, APP_TIMER_PRESCALER) /**< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (5 seconds). */
    #define NEXT_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(30000, APP_TIMER_PRESCALER) /**< Time between each call to sd_ble_gap_conn_param_update after the first call (30 seconds). */
    #define MAX_CONN_PARAMS_UPDATE_COUNT 3 /**< Number of attempts before giving up the connection parameter negotiation. */
    
    #define DEAD_BEEF 0xDEADBEEF /**< Value used as error code on stack dump, can be used to identify stack location on stack unwind. */
    
    #define UART_TX_BUF_SIZE 256 /**< UART TX buffer size. */
    #define UART_RX_BUF_SIZE 256 /**< UART RX buffer size. */
    
    
    static ble_nus_t m_nus; /**< Structure to identify the Nordic UART Service. */
    static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; /**< Handle of the current connection. */
    
    static ble_uuid_t m_adv_uuids[] = {{BLE_UUID_NUS_SERVICE, NUS_SERVICE_UUID_TYPE}}; /**< Universally unique service identifier. */
    
    static const nrf_drv_spi_t Spi = NRF_DRV_SPI_INSTANCE(1);
    
    static struct bma2x2_t bma2x2;
    
    
    
    void spi_init(void)
    {
    uint32_t err_code;
    nrf_drv_spi_config_t SpiCfg = NRF_DRV_SPI_DEFAULT_CONFIG(1);
    SpiCfg.sck_pin = SPIM1_SCK_PIN;
    SpiCfg.mosi_pin = SPIM1_MOSI_PIN;
    SpiCfg.miso_pin = SPIM1_MISO_PIN;
    SpiCfg.frequency = NRF_DRV_SPI_FREQ_8M;
    
    nrf_gpio_pin_dir_set(SPIM1_SS1_PIN, NRF_GPIO_PIN_DIR_OUTPUT);
    nrf_gpio_cfg_output(SPIM1_SS1_PIN); //Acel CS
    nrf_gpio_pin_clear(SPIM1_SS1_PIN);
    
    nrf_gpio_pin_dir_set(SPIM1_SS2_PIN, NRF_GPIO_PIN_DIR_OUTPUT);
    nrf_gpio_cfg_output(SPIM1_SS2_PIN); //Acel CS
    nrf_gpio_pin_clear(SPIM1_SS2_PIN);
    
    nrf_gpio_pin_dir_set(SPIM1_SS3_PIN, NRF_GPIO_PIN_DIR_OUTPUT);
    nrf_gpio_cfg_output(SPIM1_SS3_PIN); //Acel CS
    nrf_gpio_pin_clear(SPIM1_SS3_PIN);
    
    err_code=nrf_drv_spi_init(&Spi, &SpiCfg, NULL);
    APP_ERROR_CHECK(err_code);
    }
    
    
    void init_sensors(void)
    {
    
    bma2x2_init(&bma2x2);
    
    }
    
    
    /**@brief Function for assert macro callback.
    *
    * @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 analyse 
    * 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(DEAD_BEEF, line_num, p_file_name);
    }
    
    
    /**@brief Function for the GAP initialization.
    *
    * @details This function will set up all the necessary GAP (Generic Access Profile) parameters of 
    * the device. It also sets the permissions and appearance.
    */
    static void gap_params_init(void)
    {
    uint32_t err_code;
    ble_gap_conn_params_t gap_conn_params;
    ble_gap_conn_sec_mode_t sec_mode;
    
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
    
    err_code = sd_ble_gap_device_name_set(&sec_mode,
    (const uint8_t *) DEVICE_NAME,
    strlen(DEVICE_NAME));
    APP_ERROR_CHECK(err_code);
    
    memset(&gap_conn_params, 0, sizeof(gap_conn_params));
    
    gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL;
    gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL;
    gap_conn_params.slave_latency = SLAVE_LATENCY;
    gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT;
    
    err_code = sd_ble_gap_ppcp_set(&gap_conn_params);
    APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for handling the data from the Nordic UART Service.
    *
    * @details This function will process the data received from the Nordic UART BLE Service and send
    * it to the UART module.
    *
    * @param[in] p_nus Nordic UART Service structure.
    * @param[in] p_data Data to be send to UART module.
    * @param[in] length Length of the data.
    */
    /**@snippet [Handling the data received over BLE] */
    static void nus_data_handler(ble_nus_t * p_nus, uint8_t * p_data, uint16_t length)
    {
    for (uint32_t i = 0; i < length; i++)
    {
    while(app_uart_put(p_data[i]) != NRF_SUCCESS);
    }
    while(app_uart_put('\n') != NRF_SUCCESS);
    }
    /**@snippet [Handling the data received over BLE] */
    
    
    /**@brief Function for initializing services that will be used by the application.
    */
    static void services_init(void)
    {
    uint32_t err_code;
    ble_nus_init_t nus_init;
    
    memset(&nus_init, 0, sizeof(nus_init));
    
    nus_init.data_handler = nus_data_handler;
    
    err_code = ble_nus_init(&m_nus, &nus_init);
    APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for handling an event from the Connection Parameters Module.
    *
    * @details This function will be called for all events in the Connection Parameters Module
    * which are passed to the application.
    *
    * @note All this function does is to disconnect. This could have been done by simply setting
    * the disconnect_on_fail config parameter, but instead we use the event handler
    * mechanism to demonstrate its use.
    *
    * @param[in] p_evt Event received from the Connection Parameters Module.
    */
    static void on_conn_params_evt(ble_conn_params_evt_t * p_evt)
    {
    uint32_t err_code;
    
    if(p_evt->evt_type == BLE_CONN_PARAMS_EVT_FAILED)
    {
    err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE);
    APP_ERROR_CHECK(err_code);
    }
    }
    
    
    /**@brief Function for handling errors from the Connection Parameters module.
    *
    * @param[in] nrf_error Error code containing information about what went wrong.
    */
    static void conn_params_error_handler(uint32_t nrf_error)
    {
    APP_ERROR_HANDLER(nrf_error);
    }
    
    
    /**@brief Function for initializing the Connection Parameters module.
    */
    static void conn_params_init(void)
    {
    uint32_t err_code;
    ble_conn_params_init_t cp_init;
    
    memset(&cp_init, 0, sizeof(cp_init));
    
    cp_init.p_conn_params = NULL;
    cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY;
    cp_init.next_conn_params_update_delay = NEXT_CONN_PARAMS_UPDATE_DELAY;
    cp_init.max_conn_params_update_count = MAX_CONN_PARAMS_UPDATE_COUNT;
    cp_init.start_on_notify_cccd_handle = BLE_GATT_HANDLE_INVALID;
    cp_init.disconnect_on_fail = false;
    cp_init.evt_handler = on_conn_params_evt;
    cp_init.error_handler = conn_params_error_handler;
    
    err_code = ble_conn_params_init(&cp_init);
    APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for putting the chip into sleep mode.
    *
    * @note This function will not return.
    */
    static void sleep_mode_enter(void)
    {
    uint32_t err_code = bsp_indication_set(BSP_INDICATE_IDLE);
    APP_ERROR_CHECK(err_code);
    
    // Prepare wakeup buttons.
    err_code = bsp_btn_ble_sleep_mode_prepare();
    APP_ERROR_CHECK(err_code);
    
    // Go to system-off mode (this function will not return; wakeup will cause a reset).
    err_code = sd_power_system_off();
    APP_ERROR_CHECK(err_code);
    }
    
    /**@brief Function for handling advertising events.
    *
    * @details This function will be called for advertising events which are passed to the application.
    *
    * @param[in] ble_adv_evt Advertising event.
    */
    static void on_adv_evt(ble_adv_evt_t ble_adv_evt)
    {
    uint32_t err_code;
    
    switch (ble_adv_evt)
    {
    case BLE_ADV_EVT_FAST:
    err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING);
    APP_ERROR_CHECK(err_code);
    break;
    case BLE_ADV_EVT_IDLE:
    sleep_mode_enter();
    break;
    default:
    break;
    }
    }
    
    
    /**@brief Function for the application's SoftDevice event handler.
    *
    * @param[in] p_ble_evt SoftDevice event.
    */
    static void on_ble_evt(ble_evt_t * p_ble_evt)
    {
    uint32_t err_code;
    
    switch (p_ble_evt->header.evt_id)
    {
    case BLE_GAP_EVT_CONNECTED:
    err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
    APP_ERROR_CHECK(err_code);
    m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
    break;
    
    case BLE_GAP_EVT_DISCONNECTED:
    err_code = bsp_indication_set(BSP_INDICATE_IDLE);
    APP_ERROR_CHECK(err_code);
    m_conn_handle = BLE_CONN_HANDLE_INVALID;
    break;
    
    case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
    // Pairing not supported
    err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
    APP_ERROR_CHECK(err_code);
    break;
    
    case BLE_GATTS_EVT_SYS_ATTR_MISSING:
    // No system attributes have been stored.
    err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0);
    APP_ERROR_CHECK(err_code);
    break;
    
    default:
    // No implementation needed.
    break;
    }
    }
    
    
    /**@brief Function for dispatching a SoftDevice event to all modules with a SoftDevice 
    * event handler.
    *
    * @details This function is called from the SoftDevice event interrupt handler after a 
    * SoftDevice event has been received.
    *
    * @param[in] p_ble_evt SoftDevice event.
    */
    static void ble_evt_dispatch(ble_evt_t * p_ble_evt)
    {
    ble_conn_params_on_ble_evt(p_ble_evt);
    ble_nus_on_ble_evt(&m_nus, p_ble_evt);
    on_ble_evt(p_ble_evt);
    ble_advertising_on_ble_evt(p_ble_evt);
    bsp_btn_ble_on_ble_evt(p_ble_evt);
    
    }
    
    
    /**@brief Function for the SoftDevice initialization.
    *
    * @details This function initializes the SoftDevice and the BLE event interrupt.
    */
    static void ble_stack_init(void)
    {
    uint32_t err_code;
    
    nrf_clock_lf_cfg_t clock_lf_cfg = NRF_CLOCK_LFCLKSRC;
    
    // Initialize SoftDevice.
    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);
    
    // Subscribe for BLE events.
    err_code = softdevice_ble_evt_handler_set(ble_evt_dispatch);
    APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for handling events from the BSP module.
    *
    * @param[in] event Event generated by button press.
    */
    void bsp_event_handler(bsp_event_t event)
    {
    uint32_t err_code;
    switch (event)
    {
    case BSP_EVENT_SLEEP:
    sleep_mode_enter();
    break;
    
    case BSP_EVENT_DISCONNECT:
    err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
    if (err_code != NRF_ERROR_INVALID_STATE)
    {
    APP_ERROR_CHECK(err_code);
    }
    break;
    
    case BSP_EVENT_WHITELIST_OFF:
    err_code = ble_advertising_restart_without_whitelist();
    if (err_code != NRF_ERROR_INVALID_STATE)
    {
    APP_ERROR_CHECK(err_code);
    }
    break;
    
    default:
    break;
    }
    }
    
    
    /**@brief Function for handling app_uart events.
    *
    * @details This function will receive a single character from the app_uart module and append it to 
    * a string. The string will be be sent over BLE when the last character received was a 
    * 'new line' i.e '\n' (hex 0x0D) or if the string has reached a length of 
    * @ref NUS_MAX_DATA_LENGTH.
    */
    /**@snippet [Handling the data received over UART] */
    void uart_event_handle(app_uart_evt_t * p_event)
    {
    static uint8_t data_array[BLE_NUS_MAX_DATA_LEN];
    static uint8_t index = 0;
    uint32_t err_code;
    
    switch (p_event->evt_type)
    {
    case APP_UART_DATA_READY:
    UNUSED_VARIABLE(app_uart_get(&data_array[index]));
    index++;
    if(index<=BLE_NUS_MAX_DATA_LEN)
    {
    if ((data_array[index - 1] == '\n') || (index >= (BLE_NUS_MAX_DATA_LEN)))
    {
    
    err_code = ble_nus_string_send(&m_nus, data_array, index);
    if (err_code != NRF_ERROR_INVALID_STATE)
    {
    APP_ERROR_CHECK(err_code);
    }
    
    index = 0;
    }
    }
    if (index>BLE_NUS_MAX_DATA_LEN)
    {
    uint8_t temp=1;
    do
    {
    err_code = ble_nus_string_send(&m_nus, data_array, temp*20);
    if (err_code != NRF_ERROR_INVALID_STATE)
    {
    APP_ERROR_CHECK(err_code);
    }
    
    temp = temp +1;
    }
    while (data_array[index - 1] != '\n');
    }
    
    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;
    }
    }
    /**@snippet [Handling the data received over UART] */
    
    
    /**@brief Function for initializing the UART module.
    */
    /**@snippet [UART Initialization] */
    static void uart_init(void)
    {
    uint32_t err_code;
    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,//APP_UART_FLOW_CONTROL_ENABLED,
    false,
    UART_BAUDRATE_BAUDRATE_Baud115200
    };
    
    APP_UART_FIFO_INIT( &comm_params,
    UART_RX_BUF_SIZE,
    UART_TX_BUF_SIZE,
    uart_event_handle,
    APP_IRQ_PRIORITY_LOW,
    err_code);
    APP_ERROR_CHECK(err_code);
    }
    /**@snippet [UART Initialization] */
    
    
    /**@brief Function for initializing the Advertising functionality.
    */
    static void advertising_init(void)
    {
    uint32_t err_code;
    ble_advdata_t advdata;
    ble_advdata_t scanrsp;
    
    // Build advertising data struct to pass into @ref ble_advertising_init.
    memset(&advdata, 0, sizeof(advdata));
    advdata.name_type = BLE_ADVDATA_FULL_NAME;
    advdata.include_appearance = false;
    advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;
    
    memset(&scanrsp, 0, sizeof(scanrsp));
    scanrsp.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
    scanrsp.uuids_complete.p_uuids = m_adv_uuids;
    
    ble_adv_modes_config_t options = {0};
    options.ble_adv_fast_enabled = BLE_ADV_FAST_ENABLED;
    options.ble_adv_fast_interval = APP_ADV_INTERVAL;
    options.ble_adv_fast_timeout = APP_ADV_TIMEOUT_IN_SECONDS;
    
    err_code = ble_advertising_init(&advdata, &scanrsp, &options, on_adv_evt, NULL);
    APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for initializing buttons and leds.
    *
    * @param[out] p_erase_bonds Will be true if the clear bonding button was pressed to wake the application up.
    */
    static void buttons_leds_init(bool * p_erase_bonds)
    {
    bsp_event_t startup_event;
    
    uint32_t err_code = bsp_init(BSP_INIT_LED | BSP_INIT_BUTTONS,
    APP_TIMER_TICKS(100, APP_TIMER_PRESCALER), 
    bsp_event_handler);
    APP_ERROR_CHECK(err_code);
    
    err_code = bsp_btn_ble_init(NULL, &startup_event);
    APP_ERROR_CHECK(err_code);
    
    *p_erase_bonds = (startup_event == BSP_EVENT_CLEAR_BONDING_DATA);
    }
    
    
    /**@brief Function for placing the application in low power state while waiting for events.
    */
    static void power_manage(void)
    {
    uint32_t err_code = sd_app_evt_wait();
    APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Application main function.
    */
    int main(void)
    {
    
    int16_t accel_x;
    int16_t accel_y;
    int16_t accel_z;
    uint32_t err_code;
    bool erase_bonds;
    
    // Initialize.
    APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, false);
    uart_init();
    spi_init();
    init_sensors();
    
    bma2x2_soft_rst();
    nrf_delay_ms(10);
    
    bma2x2_set_range(BMA2x2_RANGE_8G);
    bma2x2_set_bw(BMA2x2_BW_62_50HZ);
    bma2x2_set_power_mode(BMA2x2_MODE_NORMAL);
    bma2x2_set_mode_value(BMA2x2_MODE_NORMAL);
    bma2x2_set_fifo_mode(0x02);
    
    
    buttons_leds_init(&erase_bonds);
    ble_stack_init();
    gap_params_init();
    services_init();
    advertising_init();
    conn_params_init();
    
    printf("\r\nUART Start!\r\n");
    err_code = ble_advertising_start(BLE_ADV_MODE_FAST);
    APP_ERROR_CHECK(err_code);
    
    // Enter main loop.
    for (;;)
    { 
    power_manage();
    printf("Accelerometer: ");
    printf("x: %d\t",bma2x2_read_accel_x(&accel_x));
    printf("y: %d\t",bma2x2_read_accel_y(&accel_y));
    printf("z: %d\r\n",bma2x2_read_accel_z(&accel_z));
    nrf_delay_ms(1000);
    }
    }

    I using library at: https://github.com/BoschSensortec 

    Thank you

  • The more interesting thing is how did you write the SPI read/write functions for the  BoschSensortec library? The library does not provide these functions for you, as these are platform specific. The file bma2x2_support.c show an example of how to implement this.

    Have you implemented your own read/write functions?

Related