2025-10-08 11:14 AM
Hi Guys, for an internship I am making a dual channel datalogger. So for that datalogger, I am using DS1338 RTC. Now instead of doing I2C normally, I am doing Bit-banging.
I am using Nucleo-F030R8 board for my prototyping and I am using PA0(SDA) and PA1(SDA).
After using DSO I was able to verify start condition, stop condition and slave address transfer. Also I tried to test ack by manually pulling the sda down and the output was as expected.
Now the issue is I am not able to write or read the RTC and I am getting FFFF while reading it. And there are no hardware issues as I have tested the RTC. This makes me think there is problem with my I2C read function.
Following is the snippet of code I am using for this purpose -
#define I2C1_SDA_HIGH() (GPIOA->BSRR = (1U << SDA1_PIN))
#define I2C1_SDA_LOW() (GPIOA->BSRR = (1U << (SDA1_PIN + 16)))
#define I2C1_SCL_HIGH() (GPIOA->BSRR = (1U << SCL1_PIN))
#define I2C1_SCL_LOW() (GPIOA->BSRR = (1U << (SCL1_PIN + 16)))
#define I2C1_SDA_READ() ((GPIOA->IDR >> SDA1_PIN) & 0x1)
#define I2C1_SDA_INPUT() (GPIOA->MODER &= ~(3U << (SDA1_PIN * 2))) // Input mode = 00
#define I2C1_SDA_OUTPUT() (GPIOA->MODER = (GPIOA->MODER & ~(3U << (SDA1_PIN * 2))) | (1U << (SDA1_PIN * 2)))
UINT8 i2c1_getdata(void)
{
UINT8 dat = 0;
I2C1_SDA_HIGH();
I2C1_SDA_INPUT();
for(UINT8 i = 0; i < 8; i++)
{
dat <<= 1;
I2C1_SCL_HIGH();
delay_us(I2C1_DELAY);
if(I2C1_SDA_READ()) dat |= 0x01;
I2C1_SCL_LOW();
delay_us(I2C1_DELAY);
}
I2C1_SDA_OUTPUT();
return dat;
}
void i2c1_opdata(UINT8 dat)
{
for(UINT8 i = 0; i < 8; i++)
{
if(dat & 0x80) I2C1_SDA_HIGH();
else I2C1_SDA_LOW();
I2C1_SCL_HIGH();
delay_us(I2C1_DELAY);
I2C1_SCL_LOW();
delay_us(I2C1_DELAY);
dat <<= 1;
}
i2c1_waitack();
}
void i2c1_waitack(void)
{
I2C1_SDA_HIGH();
I2C1_SDA_INPUT();
i2c1_wait_tout = I2C1_WAIT_TOUT;
I2C1_SCL_LOW();
delay_us(I2C1_DELAY);
I2C1_SCL_HIGH();
delay_us(I2C1_DELAY);
while (I2C1_SDA_READ())
{
if (i2c1_wait_tout-- == 0) break; // Timeout
delay_us(5);
}
I2C1_SCL_LOW();
delay_us(I2C1_DELAY);
I2C1_SDA_OUTPUT();
}
Help will be really appreciated!
Footnotes-
1)delay_us() is a software delay, hence not very precise, but I have fine tuned the I2C1_delay to get 100khz SCL
2)The time out for ack after calculating came out to be almost 5 us, considering 48Mhz sysclock.
2025-10-09 6:51 AM
Maybe best is say menthor , dont waste money and time, write some code for bitbang existing hw interface on same MCU .