Mbed forum

I2c channel freezes up on write when using internal pullups on scl, sda

(Steve Wald) #1

I suppose this is unorthodox, but the compiler let me do it and it actually worked for reads, but any write at all from the master to slave causes the channel to lock up until a full system reset.
I am using mbed OS2 to program a Nordic nRF51422 to talk to a Cypress CY8C20x66 over I2C, where the nRF is master and the CY8C is slave. We had hopes of removing the discreet R’s from the system by taking advantage of internal pad pullups. Note that the problem goes away when using discreet R’s instead of pad pullups.
These are code snips from the mbed main.cpp:

#include “mbed.h”
#include “BLE.h”
#include “UARTService.h”

// Device You Wish to Use Address - Kr using i2c Address 5 (*2=10)
#define I2C_Slave_ADDR (0x0a) // Slave address (preshifted left 1 bit)

//TwoWire i2c = TwoWire(NRF_TWI0);
I2C i2c(P0_2, P0_1); //(I2C_SDA, I2C_SCL); //I2C Class Pin Assignments see I2C.h
DigitalInOut i2c_sda(P0_2);
DigitalInOut i2c_scl(P0_1);

char i2cdata_read[5];
char *i2cdata_reply;
bool i2cRepeat = 0;

int main(void) {

unsigned int uifrequency = 100000; //100KHz 200KHz 400KHz available for nRF5 i2c
i2c.frequency (uifrequency);
i2c_sda.mode(PullUp); // using internal pullups on the I2C master

int rdBytes = 5;
char goByte;
uint16_t krData, krMaxDiff;

while (1) {
    if (!i2c.read(I2C_Slave_ADDR, i2cdata_read, rdBytes, i2cRepeat)) {
        goByte = i2cdata_read[0];
        krData = (i2cdata_read[1]<<8) | i2cdata_read[2];
        krMaxDiff = (i2cdata_read[3]<<8) | i2cdata_read[4];
i2cdata_reply = "g";
wrErr = i2c.write((I2C_Slave_ADDR),i2cdata_reply, 1, i2cRepeat);
if (wrErr) 
    DEBUG("\t\t\tWrite ERROR btn = %u (NACK) from Kr!. \n", wrErr);


Note that there is no error thrown by the initial i2c.write(), but afterwards both scl and sda are stuck low and all further reads or writes will throw an error.
Has anyone else run into this? Is there any workaround or solution other than using the discreets?