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

Creating the nrf_twi_mngr without the NRF_TWI_MNGR_DEF macro

Cheers, again!

Our project uses an array of different modules, many of which will need to make use of the TWI manager.

I've been able to create the manager successfully using

NRF_TWI_MNGR_DEF(m_nrf_twi_mngr, MAX_PENDING_TRANSACTIONS, TWI_INSTANCE_ID);

void twi_init (void){
  uint32_t err_code;
  ret_code_t ret;
  const nrf_drv_twi_config_t config =
  {
   .scl      = TWI_SCL,
   .sda      = TWI_SDA,
   .frequency    = NRF_TWI_FREQ_100K,
   .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
   .clear_bus_init     = false
  };
  ret = nrf_twi_mngr_init(&m_nrf_twi_mngr, &config);
  printf("twi_config nrf_twi_mngr_init %d \n", ret);
}

If the manager is defined in the same function I call
APP_ERROR_CHECK(nrf_twi_mngr_schedule(&m_nrf_twi_mngr, &accel_modeset_transaction));

It queues up fine.

However, I'm trying to extract the TWI  management into its own module (with its own .c and .h) that other modules wishing to use it can call in (such as my accelerator, my temp sensor, and other sensors). Queueing into the manager schedule within each of these require a pointer to m_nrf_twi_mngr, however when generated with the NRF_TWI_MNGR_DEF macro, &m_nrf_twi_mngr only accessible within the c file I declare it.

I've yet to figure out how to expose this to other modules who want to use it.
Defining "nrf_twi_mngr_t m_nrf_twi_mngr" in the h gives me compile errors over either conflicting qualifiers, or multiple definitions.

I've tried moving the macro into the twi.h, but I get a flood of linker errors such as:


TWI/twi.h:19: multiple definition of `m_nrf_twi_mngr_queue'
twi.h:19: first defined here

TWI/twi.h:19: multiple definition of `m_nrf_log_queue_m_nrf_twi_mngr_queue_logs_data_dynamic'
twi.h:19: first defined here

TWI/twi.h:19: multiple definition of `m_nrf_log_queue_m_nrf_twi_mngr_queue_logs_data_const'
twi.h:19: first defined here


Those 3 get repeated 9 times.


Is there a known way to instantiate the m_nrf_twi_mngr in a way that would let me expose it in other module's C files, where I can define transactions and such like so
void accel_init_cb(ret_code_t	result,	void * p_user_data){
	printf("accel_init_cb: %ld \n",result);
}
static nrf_twi_mngr_transfer_t const transfers_accel_init[]	={
	NRF_TWI_MNGR_WRITE(ACCEL_ADDRESS, accel_init_regdata, sizeof(accel_init_regdata), 0)
};
nrf_twi_mngr_transaction_t NRF_TWI_MNGR_BUFFER_LOC_IND accel_init_transaction ={
	.callback			 = accel_init_cb,
	.p_user_data		 = NULL,
	.p_transfers		 = transfers_accel_init,
	.number_of_transfers = sizeof(transfers_accel_init)	/ sizeof(transfers_accel_init[0])
};

void start_accel(){ // <--- This would be the function called in an overarching HAL.c
  APP_ERROR_CHECK(nrf_twi_mngr_schedule(&m_nrf_twi_mngr, &accel_init_transaction));
}

I can't seem to find any examples that instantiate the manager in a way that let's it be referenced from an included source; any help would be exceptionally appreciated!

Oh, and we're using SDK 15.0, SoftDevice 6.0, and the NRF5832 on a custom board, compiled with GCC

Thanks!

Parents
  • You can modify NRF_TWI_MNGR_DEF macro by removing "static" keyword from this line:

    static const nrf_twi_mngr_t _nrf_twi_mngr_name, next other files can refer so created manager by extern directive.

  • Thank you! That seems to have done the trick!
    For those following along at home (since there are few things as painful in this world as finding a thread that *almost* solves your problem, but never fully clarifies how.)

    I was able to create a twi Schedule function

    void twi_scheduler(nrf_twi_mngr_transaction_t* p_transaction) {
      uint32_t err_code;
      err_code = nrf_twi_mngr_schedule(&m_nrf_twi_mngr, p_transaction);
      APP_ERROR_CHECK(err_code);
    }

    And pass what I need from any of my modules by replacing
    APP_ERROR_CHECK(nrf_twi_mngr_schedule(&m_nrf_twi_mngr, &accel_init_transaction));
    with
    twi_scheduler(&accel_init_transaction);


    Additionally,, tweaking SDK files directly sounds like it sets up future me for a Nightmare month at work during an inevitable upgrade, But rather than changing the SDK file itself I was able to override it with:

    #ifdef NRF_TWI_MNGR_DEF
    #undef NRF_TWI_MNGR_DEF
    #define NRF_TWI_MNGR_DEF(_nrf_twi_mngr_name, _queue_size, _twi_idx) \
        NRF_QUEUE_DEF(nrf_twi_mngr_transaction_t const *,                                           \
                      _nrf_twi_mngr_name##_queue,                                                   \
                      (_queue_size),                                                                \
                      NRF_QUEUE_MODE_NO_OVERFLOW);                                                  \
        static nrf_twi_mngr_cb_t CONCAT_2(_nrf_twi_mngr_name, _cb);                                 \
        const nrf_twi_mngr_t _nrf_twi_mngr_name =                                                   \
        {                                                                                           \
            .p_nrf_twi_mngr_cb          = &CONCAT_2(_nrf_twi_mngr_name, _cb),                       \
            .p_queue                    = &_nrf_twi_mngr_name##_queue,                              \
            .twi                        = NRF_DRV_TWI_INSTANCE(_twi_idx)                            \
        }
    #endif


    Thanks again for your help!! No idea how I would have figured that out otherwise.

Reply
  • Thank you! That seems to have done the trick!
    For those following along at home (since there are few things as painful in this world as finding a thread that *almost* solves your problem, but never fully clarifies how.)

    I was able to create a twi Schedule function

    void twi_scheduler(nrf_twi_mngr_transaction_t* p_transaction) {
      uint32_t err_code;
      err_code = nrf_twi_mngr_schedule(&m_nrf_twi_mngr, p_transaction);
      APP_ERROR_CHECK(err_code);
    }

    And pass what I need from any of my modules by replacing
    APP_ERROR_CHECK(nrf_twi_mngr_schedule(&m_nrf_twi_mngr, &accel_init_transaction));
    with
    twi_scheduler(&accel_init_transaction);


    Additionally,, tweaking SDK files directly sounds like it sets up future me for a Nightmare month at work during an inevitable upgrade, But rather than changing the SDK file itself I was able to override it with:

    #ifdef NRF_TWI_MNGR_DEF
    #undef NRF_TWI_MNGR_DEF
    #define NRF_TWI_MNGR_DEF(_nrf_twi_mngr_name, _queue_size, _twi_idx) \
        NRF_QUEUE_DEF(nrf_twi_mngr_transaction_t const *,                                           \
                      _nrf_twi_mngr_name##_queue,                                                   \
                      (_queue_size),                                                                \
                      NRF_QUEUE_MODE_NO_OVERFLOW);                                                  \
        static nrf_twi_mngr_cb_t CONCAT_2(_nrf_twi_mngr_name, _cb);                                 \
        const nrf_twi_mngr_t _nrf_twi_mngr_name =                                                   \
        {                                                                                           \
            .p_nrf_twi_mngr_cb          = &CONCAT_2(_nrf_twi_mngr_name, _cb),                       \
            .p_queue                    = &_nrf_twi_mngr_name##_queue,                              \
            .twi                        = NRF_DRV_TWI_INSTANCE(_twi_idx)                            \
        }
    #endif


    Thanks again for your help!! No idea how I would have figured that out otherwise.

Children
No Data
Related