NRF52840 I2C ADDRESS.

Hello Everyone,

                           I am working on NRF52840 development kit. I am trying to run I2c master. My main goal is to send some data to slave via I2C lines. I am using the example code "TWI scanner" from the sdk examples. I have attached the slave microcontroller (ATSAMD20) and I am running i2c slave code on it. The Slave address is 0x54. I have set it as 0x54 in the slave code. Now when I try to scan the devices from NRF52840, the device is found at 0x28 address. Why is it so?? 

  • Typically i2c is 7-bit address followed by an 8th-bit that indicate read or write. Making up a total of 8-bit i2c transaction. When there is mismatch between i2c address set and the actual i2c address that the scanner finds, then it typically due to a bit shifting that occured when creating the 7-bit address on the slave (typically done by shifting the address one bit to the left, there one bit can be masked out). It is likely this is the case here, but you may need to try several adresses or use a logic analyzer to more easily understand this.

    0x54: 01010100 (shifting 1bit to the left and masking out the MSB: 0101000).
    0x28: 00101000

    At least that is what I expect. 

    Best regards,
    Kenneth

  • Thanks for your reply Kenneth. Something weird is happening at my side. I agree with your left bit shifting. I tried to test the code again. Now NRF52840 is scanning 2 addresses. 

    my code is as follows:-

    int main(void){

    ret_code_t err_code;
    uint8_t address = (0x54U); 
    uint8_t data;
    bool detected_device = false;
    bool result = false;

    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
    NRF_LOG_DEFAULT_BACKENDS_INIT();

    NRF_LOG_INFO("TWI scanner started.");
    NRF_LOG_FLUSH();
    twi_init();
    nrf_delay_ms(1000); // give some delay

    for (address = 1; address <= TWI_ADDRESSES; address++)
    {
    err_code = nrf_drv_twi_rx(&m_twi, address, &data, sizeof(data));
    if (err_code == NRF_SUCCESS)
    {
    detected_device = true;
    NRF_LOG_INFO("TWI device detected at address 0x%x...0x%x", address,data);
    NRF_LOG_FLUSH();
    send_data();
    }
    NRF_LOG_FLUSH();
    }


    void send_data(void)
    {
    ret_code_t err_code;
    uint8_t address = (0x54U);
    uint8_t sample_data=0xaa;
    uint8_t sample_data1;


    err_code = nrf_drv_twi_tx(&m_twi, address, &sample_data, sizeof(sample_data), true);
    //Wait for the transmission to get completed
    //while (m_xfer_done == false){}
    nrf_delay_ms(1000); // give some delay


    // If transmission was not successful, exit the function with false as return value
    if (NRF_SUCCESS != err_code)
    {
    NRF_LOG_INFO("FAILED 1.");
    NRF_LOG_FLUSH();
    }
    else
    {
    NRF_LOG_INFO("SUCCESS 1.");
    NRF_LOG_FLUSH();
    }

    }

    This is my log on nrf module :- 

    <info> app: TWI scanner started.
    <info> app: TWI device detected at address 0x28...0x0
    <info> app: SUCCESS 1.
    <info> app: TWI device detected at address 0x54...0xAA
    <info> app: SUCCESS 1.

    0XAA is the data which I had sent to the slave. Now why is it scanning 2 addresses when I have attached only one slave with address 0x54?? 

  • I think I read somewhere that the ATSAMD20 can support multiple (e.g. 2) i2c slave addresses?

    Kenneth

  • Thanks, I got it. I had one question. I tested my code with SDA and SCL lines as p026 and p027. Now if I want to use SCL pin as P1.09 and SDA pin as P0.11 how do I configure port 1 and port 0 seperately?

  • You can use the following macro from nrf_gpio.h:

    /** @brief Macro for mapping port and pin numbers to values understandable for nrf_gpio functions. */
    #define NRF_GPIO_PIN_MAP(port, pin) (((port) << 5) | ((pin) & 0x1F))

    e.g. scl = NRF_GPIO_PIN_MAP(1,9);

Related