Author Topic: Fast I2C 400 K Hz  (Read 7924 times)

edorphy

  • RFduino Full Member
  • ***
  • Posts: 86
  • Karma: +0/-0
    • View Profile
Fast I2C 400 K Hz
« on: February 25, 2014, 09:23:33 PM »
Hello all,
I am developing an application that requires the use of a 400 Khz I2C bus. All AVR chips can do this by modifying the TWBR (two wire baud rate) register.

Is there an equivalent register buried within the cortex chip to modify a register at a low level?
Is there a class method I'm not seeing that I can call to change the frequency?

I have found the following snip within the RFduino wire library class: (like 142/143)
Code: [Select]
// TWI clock frequency
static const uint32_t TWI_CLOCK = 100000;

However it doesn't seem to be referenced or used anywhere in the constructor of the wire class master_init method:

Code: [Select]
bool TwoWire::twi_master_init(void)
{
    /* To secure correct signal levels on the pins used by the TWI
       master when the system is in OFF mode, and when the TWI master is
       disabled, these pins must be configured in the GPIO peripheral.
    */
    NRF_GPIO->PIN_CNF[SCL_pin_number] =
        (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
      | (GPIO_PIN_CNF_DRIVE_S0D1     << GPIO_PIN_CNF_DRIVE_Pos)
      | (GPIO_PIN_CNF_PULL_Pullup    << GPIO_PIN_CNF_PULL_Pos)
      | (GPIO_PIN_CNF_INPUT_Connect  << GPIO_PIN_CNF_INPUT_Pos)
      | (GPIO_PIN_CNF_DIR_Input      << GPIO_PIN_CNF_DIR_Pos);

    NRF_GPIO->PIN_CNF[SDA_pin_number] =
        (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
      | (GPIO_PIN_CNF_DRIVE_S0D1     << GPIO_PIN_CNF_DRIVE_Pos)
      | (GPIO_PIN_CNF_PULL_Pullup    << GPIO_PIN_CNF_PULL_Pos)
      | (GPIO_PIN_CNF_INPUT_Connect  << GPIO_PIN_CNF_INPUT_Pos)
      | (GPIO_PIN_CNF_DIR_Input      << GPIO_PIN_CNF_DIR_Pos);

    twi->EVENTS_RXDREADY = 0;
    twi->EVENTS_TXDSENT = 0;
    twi->PSELSCL = SCL_pin_number;
    twi->PSELSDA = SDA_pin_number;
    twi->FREQUENCY = TWI_FREQUENCY_FREQUENCY_K100 << TWI_FREQUENCY_FREQUENCY_Pos;
    rfduino_ppi_channel_unassign(7);
    twi->ENABLE = TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos;

    return twi_master_clear_bus();
}

The only part I've been able to discern for frequency selection is this:
twi->FREQUENCY = TWI_FREQUENCY_FREQUENCY_K100 << TWI_FREQUENCY_FREQUENCY_Pos;

Where is TWI_FREWUENCY_FREQUENCY_K100 defined, and is there a named constant for K400?

I also found this in the header so the library is presumably ready to perform 400 Khz operation:
Code: [Select]
#define TWI_DELAY() delayMicroseconds(4); // Time to wait when pin states are changed. For fast-mode the delay can be zero and for standard-mode 4 us delay is sufficient

Thanks for any help!

mkay

  • RFduino Team
  • *****
  • Posts: 405
  • Karma: +15/-0
    • View Profile
Re: Fast I2C 400 K Hz
« Reply #1 on: February 26, 2014, 01:31:10 PM »
Hi Edorphy,

Try adding this line after you do a Wire.begin():

Wire.begin();
NRF_TWI1->FREQUENCY = TWI_FREQUENCY_FREQUENCY_K400 << TWI_FREQUENCY_FREQUENCY_Pos;

K100 = default 100khz
K400 = 400khz

We will look into having a method to allow an easier selection of speeds.

edorphy

  • RFduino Full Member
  • ***
  • Posts: 86
  • Karma: +0/-0
    • View Profile
Re: Fast I2C 400 K Hz
« Reply #2 on: February 27, 2014, 06:02:17 PM »
Thanks, I'll try it out!

Where is that named constant defined? What other speeds are available?

Thanks in advance!

tolson

  • Global Moderator
  • *****
  • Posts: 831
  • Karma: +19/-0
    • View Profile
    • Thomas Olson Consulting
Re: Fast I2C 400 K Hz
« Reply #3 on: February 27, 2014, 07:36:49 PM »
Check out this path...
arduino-1.5.6-r2/hardware/arduino/RFduino/system/RFduino/include/nrf51_bitfields.h

Code: [Select]

/* Register: TWI_FREQUENCY */
/* Description: Two-wire frequency. */

/* Bits 31..0 : Two-wire master clock frequency. */
#define TWI_FREQUENCY_FREQUENCY_Pos (0UL) /*!< Position of FREQUENCY field. */
#define TWI_FREQUENCY_FREQUENCY_Msk (0xFFFFFFFFUL << TWI_FREQUENCY_FREQUENCY_Pos) /*!< Bit mask of FREQUENCY field. */
#define TWI_FREQUENCY_FREQUENCY_K100 (0x01980000UL) /*!< 100 kbps. */
#define TWI_FREQUENCY_FREQUENCY_K250 (0x04000000UL) /*!< 250 kbps. */
#define TWI_FREQUENCY_FREQUENCY_K400 (0x06680000UL) /*!< 400 kbps. */


mkay

  • RFduino Team
  • *****
  • Posts: 405
  • Karma: +15/-0
    • View Profile
Re: Fast I2C 400 K Hz
« Reply #4 on: February 28, 2014, 10:23:22 AM »
That is correct, there are 3 speeds available. 100khz, 250khz and 400khz

We will be adding a method to change to allow you to easily set the speed.

mkay

  • RFduino Team
  • *****
  • Posts: 405
  • Karma: +15/-0
    • View Profile
Re: Fast I2C 400 K Hz
« Reply #5 on: March 17, 2014, 06:01:29 PM »
The wire speed enhancement is available in RFduino v1.7.2.

Usage:

Wire.speed = 400;  // select 400 kbps
Wire.begin();

The default is 100. You can optionally specify 250 or 400.

Timmmm

  • RFduino Jr. Member
  • **
  • Posts: 43
  • Karma: +3/-0
    • View Profile
Re: Fast I2C 400 K Hz
« Reply #6 on: March 31, 2014, 03:10:41 AM »
You guys should use enums for settings like this. Using an int for a value that can only actually be 100, 250 or 400 is a pretty terrible practice. What happens if I do Wire.speed = 1000? A hard-to-find bug, that's what!

cromas

  • RFduino Jr. Member
  • **
  • Posts: 26
  • Karma: +0/-0
    • View Profile
Re: Fast I2C 400 K Hz
« Reply #7 on: February 11, 2015, 06:15:05 PM »
Is there any possibility (hardware + software) for supporting Fm+ bus, i.e. 1MHz, in the future?

tolson

  • Global Moderator
  • *****
  • Posts: 831
  • Karma: +19/-0
    • View Profile
    • Thomas Olson Consulting
Re: Fast I2C 400 K Hz
« Reply #8 on: February 11, 2015, 07:10:12 PM »
Is there any possibility (hardware + software) for supporting Fm+ bus, i.e. 1MHz, in the future?

Hi cromas,

Probably best to ask that question on the Nordic nRF51822 forum site.

cromas

  • RFduino Jr. Member
  • **
  • Posts: 26
  • Karma: +0/-0
    • View Profile
Re: Fast I2C 400 K Hz
« Reply #9 on: February 13, 2015, 10:31:15 AM »
Why's that? RFD wrote the Wire library, did they not?

tolson

  • Global Moderator
  • *****
  • Posts: 831
  • Karma: +19/-0
    • View Profile
    • Thomas Olson Consulting
Re: Fast I2C 400 K Hz
« Reply #10 on: February 13, 2015, 10:43:25 AM »
It has nothing to do with software. I2C is first hardware. Nordic only specifies up to 400Khz. The software is just to make programming that hardware easier on the average user. It is whether the hardware itself is capable of running that fast. Things like internal capacitance, slew rates, current loads, etc, are all concerns.

If you know how to program the nRF51822 registers for the I2C frequency, you can try loading it with 0x10000000 or 0x10040000 and see if you can get it to come close to working. You would need to keep the bus length very short. The pullup resistors may need to be lowered to allow higher current. But you run up against the current limits of the pins themselves are limited to 5mA MAX. And only three pins total can use that amount of current. Perhaps the easiest way to experiment  is to redefine one of the variables that the software does define for you. For example change the definition K100, or K250, or K400 from whatever it is to one of the above values. Best have a storage scope or signal ananlyzer available while you experiment.


cromas

  • RFduino Jr. Member
  • **
  • Posts: 26
  • Karma: +0/-0
    • View Profile
Re: Fast I2C 400 K Hz
« Reply #11 on: February 13, 2015, 04:38:53 PM »
Excellent, thanks.

 

anything