I have an MCU (tm4c123gh6pm) in which I have configured an I2C slave device. At the moment I don't have resistors to wire the required pull-ups, so I want to use two of the MCU's GPIOs for this purpose.
I have configured two GPIOs as inputs with 'weak' pull-up resistors (not sure what 'weak' means):
static void init_pullup_resistors(void) {
GPIOPinTypeGPIOInput(GPIO_PORTB_BASE, GPIO_PIN_6);
GPIOPinTypeGPIOInput(GPIO_PORTB_BASE, GPIO_PIN_7);
GPIOPadConfigSet(GPIO_PORTB_BASE,
GPIO_PIN_6 | GPIO_PIN_7,
GPIO_STRENGTH_8MA,
GPIO_PIN_TYPE_STD_WPU);
}
I have double checked that, before wiring anything, the two I2C pins are low and the 'pull-up' pins are high.
When I connect SDA to one of the 'pull-ups' it remains high, so fine. However, when I do the same with SCL, it goes low directly. If I try to send a frame from my I2C master dev. (which is a Basys 3), I can see a clock signal in SCL, but it only reaches a few millivolts (not the expected 3.3V).
Why is this happening?
More context: I have checked the tm4c123gh6pm
datasheet and have found that its internal resistors are way bigger than what an I2C should use (4.7 kOhms):
I suspect this might be causing the problem, but I don't understand how. As you can see, those resistors are supposed to go from 13 to 35 kOhms. However, the header file documentation (TivaWare SDK) speaks about 'weak' pull-ups. I don't know what is this. See below:
#define GPIO_PIN_TYPE_STD 0x00000008 // Push-pull
#define GPIO_PIN_TYPE_STD_WPU 0x0000000A // Push-pull with weak pull-up
#define GPIO_PIN_TYPE_STD_WPD 0x0000000C // Push-pull with weak pull-down
#define GPIO_PIN_TYPE_OD 0x00000009 // Open-drain
Having that I2C requires ~4.7 kOhms pull-ups, ~13-35 don't seem weak, but rather the opposite.
Below is how I initialize the I2C slave dev.:
static void I2C1_Init(void) {
SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
GPIOPinConfigure(GPIO_PA6_I2C1SCL);
GPIOPinConfigure(GPIO_PA7_I2C1SDA);
GPIOPinTypeI2CSCL(GPIO_PORTA_BASE, GPIO_PIN_6);
GPIOPinTypeI2C(GPIO_PORTA_BASE, GPIO_PIN_7);
I2CSlaveEnable(I2C1_BASE);
I2CSlaveInit(I2C1_BASE, I2C_SLAVE_ADDRESS);
}
Best Answer
First of all "weak pull-up" means low current. Ohm law: higher the resistance, lower the current. It's a wide used term.
Next, I2C bus are open drain bus. Setting the I2C pins to push-pull can cause damage to the devices on the bus. Open drain devices only drives bus down to ground while communicating. If you have push-pull, it can cause short circuit while some device on the bus "connects" it to the ground and the other one drives it high.
Those weak pull-ups you've quoted are described in GPIO section. I.e. it's not supposed to work with the I2C. That's why it's weaker. I2C bus are usually supposed to have external pull-up resistors. Having 4.7K resistance on MCU die will consume much space which would be a waste if the user won't be using I2C Master.