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

nRF52 bug

Hello!

Apologies in advance for my english.

I already asked a similar question, here is the link to it

When trying to connect a PWM driver PCA9685, I ran into problems that are software

Here are my user files that I used

I also use the development kit nRF52-DK & SDK17

My problem is this:

I have a function

void pca9685_write_u8 (uint8_t reg,uint8_t val)
{
  uint8_t buff[2] = {reg,val};
    nrf_drv_twi_tx(&m_pcah.twi_handle,m_pcah.device_address,buff, 2, false);
}

I think it's not worth explaining what she does.I use it quite often to initialize a PWM driver. But if I copy the body of the function and replace it at the place of its use, then everything stops working. For example; 

void pca9685_sleep(void)
{
	// Read the current state of the mode 1 register.
	uint8_t mode1_reg;
	 pca9685_read_u8( PCA9685_REGISTER_MODE1, &mode1_reg);

	// Don't write the restart bit back and set the sleep bit.
	PCA9685_CLEAR_BIT_MASK(mode1_reg, PCA9685_REGISTER_MODE1_RESTART);
	PCA9685_SET_BIT_MASK(mode1_reg, PCA9685_REGISTER_MODE1_SLEEP);
	 //pca9685_write_u8( PCA9685_REGISTER_MODE1, mode1_reg);
    uint8_t buff[2] = {PCA9685_REGISTER_MODE1, mode1_reg};
    nrf_drv_twi_tx(&m_pcah.twi_handle,m_pcah.device_address,buff, 2, false);
}

And that is not all. All my code looks terrible. But this is the only thing that I got to run through trial and error.

I also collected the above sending function in a similar way 

void pca9685_write_u8 (pca9685_handle_t *m_handle,uint8_t reg,uint8_t val)
{
  uint8_t buff[2] = {reg,val};
    nrf_drv_twi_tx(&m_handle->twi_handle,m_handle->device_address,buff, 2, false);
}

but you guessed it it didn't work

This is the first time I come across such a thing. Please help me

Parents Reply Children
  •    /**
     * @brief TWI events handler.
     */
    void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
    {
        switch (p_event->type)
        {
            case NRF_DRV_TWI_EVT_DONE:
                m_xfer_done = true;
                break;
            default:
                break;
        }
    }
    /**
     * @brief TWI initialization.
     */
    void twi_init (void)
    {
        ret_code_t err_code;
    
        const nrf_drv_twi_config_t twi_lm75b_config = {
           .scl                = 27,
           .sda                = 26,
           .frequency          = NRF_DRV_TWI_FREQ_400K,
           .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
           .clear_bus_init     = false
        };
    
        err_code = nrf_drv_twi_init(&m_twi, &twi_lm75b_config, twi_handler, NULL);
                NRF_LOG_INFO("\r\n nrf_drv_init = %d",err_code);
        NRF_LOG_FLUSH();
        APP_ERROR_CHECK(err_code);
    
        nrf_drv_twi_enable(&m_twi);
    } 

  • When you're using an event handler in nrf_drv_twi_init(), TWI driver works in async mode - nrf_drv_twi_tx() returns immediately, transaction continues at background. There are two consequences to make your code stable:

    1) you should wait for transaction to finish before sending a next one. If you're using a flag that is set in event handler by NRF_DRV_TWI_EVT_DONE event, don't forget to define that flag with volatile keyword.

    2) automatic variable should not be used for tx buffer, because its content will likely be destroyed before transaction is finished. Define your buffer as  static uint8_t buff[2].

Related