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

TWIS EEPROM Simulator does not send first bit properly.

Hi,

I was exploring TWI master with TWIS Slave example in SDK16.0.0. 

It works for sequential reads in loop-back mode.

Now I connected the simulated eeprom slave to another MCU on another devboard. This MCU does sequential reads on 1024 byte boundaries. So I adjusted the example code's config.h to cater for the MCU's requirements. Everything appears to be working (so I thought). But upon closer inspection, I found out that BIT 7 of the first BYTE sent out by the TWIS is always '0'. For example the actual byte was a 0xFF, I could only see 0x7F being sent out in my logic analyzer. The MCU also receives 0x7F instead of 0xFF. This only happens to the first byte of any sequential read transaction. It does not affect the other succeeding bytes.

The MCU (TW master) follows what is described on Figure 185 of nRF52840 PS v1.1 page 488. Except it reads 1024 bytes after and not just 4.

"Figure 185: A repeated start sequence, where the TWI master writes two bytes followed by reading four bytes from the slave"

The MCU reads 1024 bytes @ address 0x0000, then issues the next Sequential Read command to address 0x0400, then to 0x0800 and so on... until 0xFC00.

All the FIRST BYTES of those addresses get's sent out as 0x7F instead of 0xFF. In short, BIT 7 is always set to '0' on all the first BYTES of any Sequential Read Transaction.

The only thing I modified in eeprom_simulator.c is adding the option to take the Read Address in ees_readBegin. 

    /**
     * @brief Start after the READ command.
     *
     * Function sets pointers for TWIS to transmit data from the current address to the end of memory.
     */
    static void ees_readBegin(void)
    {			  
        uint32_t read_len = EEPROM_SIM_SEQ_READ_MAX_BYTES;
						
#if (EEPROM_SIM_ADDRESS_LEN_BYTES == 1)
        ees_setAddr(m_rxbuff[0]);
#endif

#if (EEPROM_SIM_ADDRESS_LEN_BYTES == 2)
        uint16_t rxbuff;

        if (TWI_ADDRESS_CONFIG == LITTLE_ENDIAN)
        {
            rxbuff = ((m_rxbuff[1] << 8 ) | (m_rxbuff[0]));
        }
        else
        {
            rxbuff = ((m_rxbuff[0] << 8 ) | (m_rxbuff[1]));
        }

        ees_setAddr(rxbuff);
				
#endif

        volatile uint16_t temp_addr = m_addr;

        if (m_addr + EEPROM_SIM_SEQ_READ_MAX_BYTES > sizeof(m_memory))
        {
            read_len = EEPROM_SIM_SIZE - m_addr;
            temp_addr = 0;
        }

        (void) nrf_drv_twis_tx_prepare(&m_twis, m_memory + m_addr, read_len);
        m_addr = temp_addr;

    }

Here is my config.h

/**
 * Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form, except as embedded into a Nordic
 *    Semiconductor ASA integrated circuit in a product or a software update for
 *    such product, must reproduce the above copyright notice, this list of
 *    conditions and the following disclaimer in the documentation and/or other
 *    materials provided with the distribution.
 *
 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * 4. This software, with or without modification, must only be used with a
 *    Nordic Semiconductor ASA integrated circuit.
 *
 * 5. Any software provided in binary form under this license must not be reverse
 *    engineered, decompiled, modified and/or disassembled.
 *
 * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */
/**
 * @ingroup twi_master_with_twis_slave_example
 * @defgroup twi_master_with_twis_slave_example_config Example code configuration
 *
 * Configuration for the code presenting TWIS and TWI functionality.
 * @{
 */

#ifndef TWI_MASTER_WITH_TWIS_SLAVE_CONFIG_H__
#define TWI_MASTER_WITH_TWIS_SLAVE_CONFIG_H__

#ifdef __cplusplus
extern "C" {
#endif

#define EEPROM_SIM_SIZE                   (65536u) //!< Simulated EEPROM size.

/* Maximum number of bytes writable to this slave emulator in one sequential access including
 * address of the slave memory. Maximum allowed is 255.
 * Note that separate RAM is allocated for the data to be written to slave.
 */
#define EEPROM_SIM_SEQ_WRITE_MAX_BYTES    128

/* Maximum number of bytes writable to this slave emulator in one sequential access.
   Maximum allowed is 255.
 */
#define EEPROM_SIM_SEQ_READ_MAX_BYTES     1024     //<! Number of data bytes transfer in single request

#define EEPROM_SIM_ADDR                   0x50    //!< Simulated EEPROM TWI slave address.


#define EEPROM_SIM_SCL_S         30   //!< Slave SCL pin.
#define EEPROM_SIM_SDA_S         31   //!< Slave SDA pin.

#define EEPROM_SIM_TWIS_INST     1    //!< TWIS interface used by EEPROM simulator.

/* Flash start address to load the RAM with at startup */
#define EEPROM_SIM_FLASH_ADDRESS  0x40000

/* Slave memory addressing byte length */
#define EEPROM_SIM_ADDRESS_LEN_BYTES    2

/* if EEPROM_SIM_ADDRESS_LEN_BYTES == 2, below will configure which byte is sent first by master */
/**
 * @enum address_byte_endian
 * @brief Endianness of the address byte that is received from master.
 */
typedef enum
{
    /*lint -save -e30*/
    BIG_ENDIAN = 0,   /**< MSB is sent first by master for address. */
    LITTLE_ENDIAN,    /**< LSB is sent first by master for address. */
} address_byte_endian;

#define TWI_ADDRESS_CONFIG    BIG_ENDIAN

/* Master Configuration */
#define MASTER_TWI_INST     0       //!< TWI interface used as a master accessing EEPROM memory.
#define UART_TX_BUF_SIZE    1024    //!< UART TX buffer size.
#define UART_RX_BUF_SIZE    32      //!< UART RX buffer size.
#define TWI_SCL_M           3       //!< Master SCL pin.
#define TWI_SDA_M           4       //!< Master SDA pin.
#define IN_LINE_PRINT_CNT   (16u)   //!< Number of data bytes printed in a single line.


/** @} */

#ifdef __cplusplus
}
#endif

#endif // TWI_MASTER_WITH_TWIS_SLAVE_CONFIG_H__

Take note

define EEPROM_SIM_FLASH_ADDRESS  0x40000

There is nothing specific @ 0x40000. It is a blank area with just 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF....

What the MCU gets when it tries to read it is 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF..

It does not matter what address the MCU tries to read. The first BYTE of that Read Address will always be affected and will always loose the first bit to '0'. 

Is this an issue with the EasyDma ?

Best Regards,

Brad

 

Parents
  • Hi,

    I tried to reproduce this with the twi_master_with_twis_slave example, but I'm not able to see this issue with your changes added. Are you able to reproduce this with the nRF52840 as master as well, or only with the external MCU? Have you checked the TWI bus with a logic analyzer, to see if 0x7F is actually being transmitted, or if it is the external MCU that does not receive the data properly?

    uart_cli:~$ eeprom read
    000: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    010: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    020: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    030: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    040: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    050: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    060: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    070: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    080: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    090: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    0A0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    0B0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    0C0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    0D0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    0E0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    0F0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    100: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    110: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    120: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    130: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    140: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    150: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    160: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    170: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    180: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    190: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    1A0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    1B0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    1C0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    1D0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    1E0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    1F0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................

    Best regards,
    Jørgen

Reply
  • Hi,

    I tried to reproduce this with the twi_master_with_twis_slave example, but I'm not able to see this issue with your changes added. Are you able to reproduce this with the nRF52840 as master as well, or only with the external MCU? Have you checked the TWI bus with a logic analyzer, to see if 0x7F is actually being transmitted, or if it is the external MCU that does not receive the data properly?

    uart_cli:~$ eeprom read
    000: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    010: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    020: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    030: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    040: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    050: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    060: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    070: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    080: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    090: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    0A0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    0B0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    0C0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    0D0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    0E0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    0F0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    100: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    110: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    120: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    130: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    140: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    150: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    160: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    170: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    180: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    190: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    1A0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    1B0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    1C0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    1D0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    1E0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
    1F0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................

    Best regards,
    Jørgen

Children
Related