Hi,
I am doing a project involving mentioned PIC and ESP32S3 communication via I2C, when PIC is master, ESP is slave. I have already accomplished the master write scenario, it works with no problems. But now I want to do a master read, and the problem is that the PIC would not send any ACK/NACK bit after the slave has sent a data byte. My friend is writing the code for ESP32, he has written a test code putting exact data byte into the I2C buffer that we see in the logic analyzer, also the ESP32 sends correct ACK bit after it's address, so it is very unlikely there are any problems with the ESP32. However, the testing code is designed to test PIC32 reading one data byte from the ESP32, so the PIC should send a NACK after the last data bit has been sent from the ESP. As you can see in the logic analyzer, there is no NACK bit, also the ninth SCL pulse is missing, even though I have set the corresponding ACKDT and ACKEN bits of the I2CCON register. Wiring is correct, 5.1k pull-ups, 100 kbits (but the problem has to be in the software...) Any observations?
main.c
I am doing a project involving mentioned PIC and ESP32S3 communication via I2C, when PIC is master, ESP is slave. I have already accomplished the master write scenario, it works with no problems. But now I want to do a master read, and the problem is that the PIC would not send any ACK/NACK bit after the slave has sent a data byte. My friend is writing the code for ESP32, he has written a test code putting exact data byte into the I2C buffer that we see in the logic analyzer, also the ESP32 sends correct ACK bit after it's address, so it is very unlikely there are any problems with the ESP32. However, the testing code is designed to test PIC32 reading one data byte from the ESP32, so the PIC should send a NACK after the last data bit has been sent from the ESP. As you can see in the logic analyzer, there is no NACK bit, also the ninth SCL pulse is missing, even though I have set the corresponding ACKDT and ACKEN bits of the I2CCON register. Wiring is correct, 5.1k pull-ups, 100 kbits (but the problem has to be in the software...) Any observations?
main.c
main.c:
#include <xc.h>
#include "configurations_bits.h"
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include "stdio.h"
#include <sys/attribs.h>
#include "delay.h"
#include "inter_integrated_circuit_protocol.h"
#include "liquid_crystal_display.h"
#include "pulse_width_modulation.h"
#include "timer.h"
#include "state_change_interrupts.h"
#include "analog_to_digital_conversion.h"
#define ESP32_WRITE (0B01100000)
#define ESP32_READ (0B01100001)
uint8_t test = 0;
int main(void) {
Inter_Integrated_Circuit_Setup ();
Inter_Integrated_Circuit_Enable ();
delay_ms(400);
Inter_Integrated_Circuit_Start();
Inter_Integrated_Circuit_Write(ESP32_READ);
test = Inter_Integrated_Circuit_Read(1);
Inter_Integrated_Circuit_Stop();
while (true){
}
return (EXIT_FAILURE);
}
inter_integrated_circuit_protocol.c:
#include <xc.h>
#include <stdint.h>
#include "inter_integrated_circuit_protocol.h"
#include "delay.h"
void Inter_Integrated_Circuit_Setup (void){
I2C1BRG = 0xEC;
I2C1CON = 0x00000000;
I2C1CONbits.SDAHT = 0b0;
I2C1CONbits.SIDL = 0b0;
I2C1CONbits.SCLREL = 0b1;
I2C1CONbits.STREN = 0b0;
I2C1CONbits.DISSLW = 0b1;
I2C1CONbits.SMEN = 0b0;
}
void Inter_Integrated_Circuit_Enable (void){
I2C1CONbits.ON = 0b1;
}
void Inter_Integrated_Circuit_Disable (void){
I2C1CONbits.ON = 0b0;
}
void Inter_Integrated_Circuit_State (void){
while( (I2C1CON & 0x0000001F) || (I2C1STAT & 0x00000004) );
}
void Inter_Integrated_Circuit_Start (void){
Inter_Integrated_Circuit_State ();
I2C1CONbits.SEN = 0b1;
}
void Inter_Integrated_Circuit_Stop (void){
Inter_Integrated_Circuit_State ();
I2C1CONbits.PEN = 0b1;
}
void Inter_Integrated_Circuit_Repeated_Start (void){
Inter_Integrated_Circuit_State ();
I2C1CONbits.RSEN = 0b1;
}
void Inter_Integrated_Circuit_Write (uint8_t I2C_data){
Inter_Integrated_Circuit_State ();
while(I2C1STATbits.TBF != 0);
I2C1TRN = I2C_data;
while(I2C1STATbits.TRSTAT != 0);
if(I2C1STATbits.ACKSTAT == 0){
}
else delay_ms(1000);
}
uint8_t Inter_Integrated_Circuit_Read (uint8_t LastRead){
uint32_t I2C_raw_data = 0;
uint8_t I2C_data = 0;
Inter_Integrated_Circuit_State ();
I2C1CONbits.RCEN = 0b1;
while(I2C1STATbits.RBF != 0);
I2C_raw_data = I2C1RCV;
I2C_data = (I2C_raw_data & 0x000000FF);
if(LastRead){
I2C1CONbits.ACKDT = 0b1; //Set NACK for acknowledge sequence
I2C1CONbits.ACKEN = 0b1; //Initiate acknowledge sequence
}
else {
I2C1CONbits.ACKDT = 0b0; //Set ACK for acknowledge sequence
I2C1CONbits.ACKEN = 0b1; //Initiate acknowledge sequence
}
return (I2C_data);
}