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

TWI reading issue

Hello,

I am using a nRF DK (nRF52832 - PCA10040 - SDK 15) to communicate with a custom electronic device developed by my own company (which integrates an 1-Wire slave).
The communication protocol is 1-Wire so I use a Single-Channel 1-Wire Master called DS2482-100 from Maxim Integrated, it is an I²C-to-1-Wire bridge device (datasheet here). 
      -------------                             -------------                           ------------------
     |               |                            |               |                         |                      |

     | nRF DK | ----- I²C/TWI ----- | DS2482 | ----- 1Wire ----- | 1Wire Slave |
     |               |                            |               |                         |                      |
      -------------                             -------------                           ------------------

I rewrote the code from Maxim Integrated (see this) by using the twi nrf driver.
The I²C original functions were replaced by nrf_drv_twi functions.

                      int I2C_write(unsigned char data, int expect_ack)   -------->   nrf_drv_twi_tx(&m_twi, TWI_address, twi_data_write, sizeof(twi_data_write), false)
                      unsigned char I2C_read(int ack)                              -------->   nrf_drv_twi_rx(&m_twi, TWI_address, &m_twi_data_read, sizeof(m_twi_data_read))

Everything works fine when I want to do a ROM research or to write a byte (1-Wire protocol).   

My issue comes from the data read. It seems like there is a bit shift somewhere. 
I have three 1-Wire commands for testing with my custom device.

1) Turn on LED of the custom device (it works, so writing is ok)
    Expected result : 4 bytes (hexadecimal) 0000AAAA
       Current result : 4 bytes (hexadecimal) 00005455

2) Turn off LED of the custom device (it works, so writing is ok)
    Expected result : 4 bytes (hexadecimal) 0000AAAA
       Current result : 4 bytes (hexadecimal) 00005455


3) Information request (no action from the custom device)
    Expected result : 5 bytes (hexadecimal) 0000110108
       Current result : 5 bytes (hexadecimal) 0000220210

I don't know where the problem comes from because the byte writing and the ROM research work.

Here is my code for OWReadByte function :

//--------------------------------------------------------------------------
// Send 8 bits of read communication to the 1-Wire Net and return the
// result 8 bits read from the 1-Wire Net.
//
// Returns:  8 bits read from 1-Wire Net
//
unsigned char OWReadByte(void)
{
    // 1-Wire Read Bytes (Case C)
    //   S AD,0 [A] 1WRB [A] Sr AD,1 [A] [Status] A [Status] A\
    //                                   \--------/
    //                     Repeat until 1WB bit has changed to 0
    //   Sr AD,0 [A] SRP [A] E1 [A] Sr AD,1 [A] DD A\ P
    //
    //  [] indicates from slave
    //  DD data read

    ret_code_t err_code;
    uint8_t twi_config_write[] = {CMD_1WRB};
    
    err_code = nrf_drv_twi_tx(&m_twi, TWI_address, twi_config_write, sizeof(twi_config_write), true);
    APP_ERROR_CHECK(err_code);
    
    int poll_count = 0;

    //m_twi_data_read = NULL;
    do
    {
        err_code = nrf_drv_twi_rx(&m_twi, TWI_address, &m_twi_data_read, sizeof(m_twi_data_read));
        APP_ERROR_CHECK(err_code);
        //__LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "[OWWait_1WB_0()] do while : m_twi_data_read 0x%.2x\n", m_twi_data_read);
    }
    while ((m_twi_data_read & STATUS_1WB) && (poll_count++ < POLL_LIMIT));
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "[OWWait_1WB_0()] apres do while : m_twi_data_read 0x%.2x\n", m_twi_data_read);

    // check for failure due to poll limit reached
    if (poll_count >= POLL_LIMIT)
    {
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "[OWWait_1WB_0()] Poll limit reached.\n");
        DS2482_reset();
        return FALSE;
    }

    uint8_t twi_data_write[] = {CMD_SRP, RGT_READ_D};   //Read Data Register
    
    err_code = nrf_drv_twi_tx(&m_twi, TWI_address, twi_data_write, sizeof(twi_data_write), false);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_twi_rx(&m_twi, TWI_address, &m_twi_data_read, sizeof(m_twi_data_read));
    APP_ERROR_CHECK(err_code);

    return ((unsigned char) m_twi_data_read);
}
 

And the initialization :

//--------------------------------------------------------------------------
// Perform a twi initialisation
//
void twi_init(void)
{
    ret_code_t err_code;

    const nrf_drv_twi_config_t twi_config = {
       .scl                = SCL_PIN,
       .sda                = SDA_PIN,
       .frequency          = NRF_DRV_TWI_FREQ_100K,
       .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
       .clear_bus_init     = false
    };

    err_code = nrf_drv_twi_init(&m_twi, &twi_config, NULL, NULL);
    APP_ERROR_CHECK(err_code);

    nrf_drv_twi_enable(&m_twi);

    //DS2482 reset and config
    DS2482_detect(DS2482_ADDR);
}
 

Thanks for your help,

Matthieu

Parents
  • Hi,

    Did you check the TWI bus with a logic analyzer, to see if the shifted data is output by the DS2482, or if it is read wrong somehow by the nRF52832? If the data on the bus is incorrect, you need to check with Maxim why the device outputs the shifted data.

    Best regards,
    Jørgen

  • Hi Jorgen,

    Thanks for your answer. This has helped me realise that my problem was due to a wrong DS2482 configuration (when I want to write a command and read several bytes).

    Kind regards,
    Matthieu 

  • Would you mind sharing the working version of your code above or at least the part you corrected? I'll be implementing the -800 version of this chip in the next few days as well with the nRF9160.

  • Hello Picsil, I can't share all my code (see this) but I would explain my modifications. Maybe this is due to the custom 1Wire devices I use. First, you could try to follow the DS2482 datasheet and then, if there is an issue, test my solution.

    Example from the datasheet "1Wire Read Byte" (Case C)

      
    According to the datasheet, your code should follow this sequence

    NB : my ROM address is 551964D90200000082 and my command 2D64081DFB00E7000A010102E771 returns 4 bytes.

    I will use this notation : 
    W = Write -> Byte wryte
    R = Read -> Byte read
    B = Busy -> Read until 1WB has changed to 0

    W - B4 (CMD_1WRS)
    B
    W - A5, 55 (ROM)

    W - A5, 19 (ROM)

    W - A5, 64 (ROM)

    W - A5, D9 (ROM)

    W - A5, 02 (ROM)

    W - A5, 00 (ROM)

    W - A5, 00 (ROM)

    W - A5, 00 (ROM)

    W - A5, 82 (ROM)

    W - A5, 2D (CMD)

    W - A5, 64 (CMD)

    W - A5, 08 (CMD)

    W - A5, 1D (CMD)

    W - A5, FB (CMD)

    W - A5, 00 (CMD)

    W - A5, E7 (CMD)

    W - A5, 00 (CMD)

    W - A5, 0A (CMD)

    W - A5, 01 (CMD)

    W - A5, 01 (CMD)

    W - A5, 02 (CMD)

    W - A5, E7 (CMD)

    W - A5, 71 (CMD)

    W - 96 (CMD_1WRB)

    W - E1, E1 (CMD_SRP, RGT_READ_D)
    R (Read byte 1)
    W - 96

    W - E1, E1 (CMD_SRP, RGT_READ_D)
    R (Read byte 2)
    W - 96

    W - E1, E1 (CMD_SRP, RGT_READ_D)
    R (Read byte 3)
    W - 96

    W - E1, E1 (CMD_SRP, RGT_READ_D)
    R (Read byte 4)

    Using this, the 4 bytes returned were incorrect. I had to change the sequence

    W - E1, F0 (CMD_SRP, RGT_STATUS)
    B
    W - B4 (CMD_1WRS)
    B
    W - A5, 55 (ROM)

    W - A5, 19 (ROM)

    W - A5, 64 (ROM)

    W - A5, D9 (ROM)

    W - A5, 02 (ROM)

    W - A5, 00 (ROM)

    W - A5, 00 (ROM)

    W - A5, 00 (ROM)

    W - A5, 82 (ROM)

    W - E1, F0 (CMD_SRP, RGT_STATUS)
    B
    W - A5, 2D (CMD)

    W - A5, 64 (CMD)

    W - A5, 08 (CMD)

    W - A5, 1D (CMD)

    W - A5, FB (CMD)

    W - A5, 00 (CMD)

    W - A5, E7 (CMD)

    W - A5, 00 (CMD)

    W - A5, 0A (CMD)

    W - A5, 01 (CMD)

    W - A5, 01 (CMD)

    W - A5, 02 (CMD)

    W - A5, E7 (CMD)

    W - A5, 71 (CMD)

    W - E1, F0 (CMD_SRP, RGT_STATUS)
    B
    W - E1, F0 (CMD_SRP, RGT_STATUS)
    B
    W - 87, 80 (CMD_1WSB, STATUS_DIR)
    B
    W - E1, F0 (CMD_SRP, RGT_STATUS)
    B
    W - 96 (CMD_1WRB)

    W - E1, E1 (CMD_SRP, RGT_READ_D)
    R (Read byte 1)
    W - 96

    W - E1, E1 (CMD_SRP, RGT_READ_D)
    R (Read byte 2)
    W - 96

    W - E1, E1 (CMD_SRP, RGT_READ_D)
    R (Read byte 3)
    W - 96

    W - E1, E1 (CMD_SRP, RGT_READ_D)
    R (Read byte 4)

    The code from Maxim Integrated is a good start. Depending on the 1W devices you want to communicate with.

    Hope it will help you,

    Matthieu 

Reply
  • Hello Picsil, I can't share all my code (see this) but I would explain my modifications. Maybe this is due to the custom 1Wire devices I use. First, you could try to follow the DS2482 datasheet and then, if there is an issue, test my solution.

    Example from the datasheet "1Wire Read Byte" (Case C)

      
    According to the datasheet, your code should follow this sequence

    NB : my ROM address is 551964D90200000082 and my command 2D64081DFB00E7000A010102E771 returns 4 bytes.

    I will use this notation : 
    W = Write -> Byte wryte
    R = Read -> Byte read
    B = Busy -> Read until 1WB has changed to 0

    W - B4 (CMD_1WRS)
    B
    W - A5, 55 (ROM)

    W - A5, 19 (ROM)

    W - A5, 64 (ROM)

    W - A5, D9 (ROM)

    W - A5, 02 (ROM)

    W - A5, 00 (ROM)

    W - A5, 00 (ROM)

    W - A5, 00 (ROM)

    W - A5, 82 (ROM)

    W - A5, 2D (CMD)

    W - A5, 64 (CMD)

    W - A5, 08 (CMD)

    W - A5, 1D (CMD)

    W - A5, FB (CMD)

    W - A5, 00 (CMD)

    W - A5, E7 (CMD)

    W - A5, 00 (CMD)

    W - A5, 0A (CMD)

    W - A5, 01 (CMD)

    W - A5, 01 (CMD)

    W - A5, 02 (CMD)

    W - A5, E7 (CMD)

    W - A5, 71 (CMD)

    W - 96 (CMD_1WRB)

    W - E1, E1 (CMD_SRP, RGT_READ_D)
    R (Read byte 1)
    W - 96

    W - E1, E1 (CMD_SRP, RGT_READ_D)
    R (Read byte 2)
    W - 96

    W - E1, E1 (CMD_SRP, RGT_READ_D)
    R (Read byte 3)
    W - 96

    W - E1, E1 (CMD_SRP, RGT_READ_D)
    R (Read byte 4)

    Using this, the 4 bytes returned were incorrect. I had to change the sequence

    W - E1, F0 (CMD_SRP, RGT_STATUS)
    B
    W - B4 (CMD_1WRS)
    B
    W - A5, 55 (ROM)

    W - A5, 19 (ROM)

    W - A5, 64 (ROM)

    W - A5, D9 (ROM)

    W - A5, 02 (ROM)

    W - A5, 00 (ROM)

    W - A5, 00 (ROM)

    W - A5, 00 (ROM)

    W - A5, 82 (ROM)

    W - E1, F0 (CMD_SRP, RGT_STATUS)
    B
    W - A5, 2D (CMD)

    W - A5, 64 (CMD)

    W - A5, 08 (CMD)

    W - A5, 1D (CMD)

    W - A5, FB (CMD)

    W - A5, 00 (CMD)

    W - A5, E7 (CMD)

    W - A5, 00 (CMD)

    W - A5, 0A (CMD)

    W - A5, 01 (CMD)

    W - A5, 01 (CMD)

    W - A5, 02 (CMD)

    W - A5, E7 (CMD)

    W - A5, 71 (CMD)

    W - E1, F0 (CMD_SRP, RGT_STATUS)
    B
    W - E1, F0 (CMD_SRP, RGT_STATUS)
    B
    W - 87, 80 (CMD_1WSB, STATUS_DIR)
    B
    W - E1, F0 (CMD_SRP, RGT_STATUS)
    B
    W - 96 (CMD_1WRB)

    W - E1, E1 (CMD_SRP, RGT_READ_D)
    R (Read byte 1)
    W - 96

    W - E1, E1 (CMD_SRP, RGT_READ_D)
    R (Read byte 2)
    W - 96

    W - E1, E1 (CMD_SRP, RGT_READ_D)
    R (Read byte 3)
    W - 96

    W - E1, E1 (CMD_SRP, RGT_READ_D)
    R (Read byte 4)

    The code from Maxim Integrated is a good start. Depending on the 1W devices you want to communicate with.

    Hope it will help you,

    Matthieu 

Children
No Data
Related