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

How can I avoid sending a repeated start between TWI write and TWI read?

I am communicating with a temperature sensor (MLX90614), which has flag register. However, in order to read this register, I must send a read sequence without issuing the repeated start between the write and read operations. Here is what I want to do in a step-by-step approach:

  1. Send start
  2. Send the slave address ID with the nWrite bit low (8 bits)
  3. Receive an ACK from the slave
  4. Send out the command to read the flags, 0xF0 (8 bits)
  5. Receive an ACK from the slave
  6. Do not send a repeated start. (Normally, there would be a repeated start here).
  7. Send the slave address with the nWrite bit high, indicating a read (8 bits)
  8. Send out 16 bits of clock to read in the MSB and LSB from the slave, placing ACKs appropriately.
  1. Issue a stop.

I think that I need to use GPIOTE with PPI to get this to work, but do not know how to specify the number of toggles that would be needed to describe the event. And upon describing the event, what action should be taken.

Can someone advise?

Thank you,

Noah

  • Why don't you use the driver in the SDK; nrf_drv_twi? If the no_stop flag in nrf_drv_tx(..) is false it should not issue a repeated start condition.

  • Ole, I have not observed this to be sufficient; the repeated start is sent whether this parameter is set to "true" or reset to "false. As the function parameter's description states:

    "If set, the stop condition is not generated on the bus after the transfer has completed successfully (allowing for a repeated start in the next transfer)."

    What I need is the ability to start the "read" command without this command initiating another start. Or perhaps I am thinking about this incorrectly. Is there a way to transfer data packets from the slave device without using the "read" command; can the "write" command be used to get data back?

    A simpler solution would be the best, but I cannot find it and that is why I mentioned the GPIOTE - PPI approach.

  • You can use the APP_TWI module. There you have the app_twi_perform function that gets a list of the twi tasks to execute. These tasks can be read or write, and they have the option not to issue the stop condition. You can have a list of tasks as follow:

    1. WRITE register address (set no_stop = true - after this write you don't want to issue the stop condition because a READ will follow immediately).

    2. READ (this time no_stop should be set to false.

    When you set no_stop = true for the Write operation instead of issuing the stop condition it will let the following Read issue its start condition. The stop condition has to be present at the end of this Read. What version of the SDK do you have?

    At the end your secvention will look like this:

    START COND | ADDR + Write bit | REG ADDR | START COND | ADDR + Read bit | | STOP COND.

  • I do not understand this answer! The write function does not have a "no repeat start bit flag"! Here is the prototype, and as you can see, the flag is for either including or not including a stop at the end of the write transaction. But, I have tried both setting and resetting the "no_stop" flag, and this has no affect on the repeated start: ret_code_t nrf_drv_twi_tx(nrf_drv_twi_t const * p_instance, uint8_t address, uint8_t const * p_data, uint8_t length, bool no_stop);

  • If you look in the MLX90614 datasheet at pages 14 and 15 you will see how the bus protocol looks like for a read or write. If you look closely you will notice that what you want for a sequential WRITE READ is to send a repeated start condition (the READ will produce it) but you do not want to to issue a stop condition after the WRITE.

    Your step 6 is wrong. You do want a start condition. What you don't want is a stop one before de read.

Related