0

I am developing a project that involves PIC32MK1024MCM064 communication with ESP32S3 and PCF8574 IO expander (for 16x2 LCD screen) via I2C. I have absolutely no problems with the PCF8574, I am getting my data packets, LCD screen works perfectly.

However, I tested the same I2C code in communication with ESP32S3 (PIC32 as master, ESP32S3 as slave), and I faced a problem with the ACK bit (It seems that PIC32 does not release the SDA line, so the ESP32S3 can not pull it down, thus sending an ACK, but that is just a guess.) I am using 5.1k pullups, standard 100Kbit/s (actually getting 95-97 KBit, I guess this is tolerable), wiring is correct, addresses are also correct.

The strangest thing is that my friend wrote the code for ESP32S3 as an I2C slave. He gets correct data packets with ACK when testing between two ESP32S3s (one as a master, the other as a slave.)

Generally speaking, me and my friend are both getting correct code results when testing in our own environments (PIC32 <-> PCF8574 and ESP32S3 <-> ESP32S3), but we can not communicate between the different MCU`s getting ACKs. I am not experienced with I2C, but I am feeling like there is something with the configuration... Maybe some clock mismatch or something else that I dont even know... This is our last step in completing a major project, so any help, advice or observation is really appreciated. Thank you in advance.

PIC32:

main:

    #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" 

    #define ESP32 (0B1100000)   //Write address
    #define LCD (0B1000000)     //Write address
 
     uint8_t Number = 0x71;  //Random value

        int main(void) { 
        
        
        ANSELA = 0x00000000;                                                                     
        ANSELB = 0x00000000;                                                                      
        ANSELC = 0x00000000;                                                                      
        ANSELE = 0x00000000;                                                                      
        ANSELG = 0x00000000;                                                                      
       
        
        TRISCbits.TRISC11 = 0b1;           //RC11 PIN_24 ADC pin for battery 
        TRISAbits.TRISA1 = 0b1;            //RA1 PIN_14 Particle detection 
        TRISCbits.TRISC7 = 0b1;            //RC7 PIN_51 First GUI button
        TRISCbits.TRISC8 = 0b1;            //RC8 PIN_52 Second GUI button
        TRISEbits.TRISE15 = 0b1;           //RE15 PIN_30 Third GUI button
        TRISEbits.TRISE14 = 0b1;           //RE14 PIN_29 Fourth GUI button
        TRISDbits.TRISD5 = 0b1;            //RD5 PIN_53 Encoder channel A
        TRISDbits.TRISD6 = 0b1;            //RD5 PIN_54 Encoder channel B
        TRISGbits.TRISG6 = 0b1;            //RG6 PIN_4 ESP32 -> PIC32 communication
        TRISAbits.TRISA11 = 0b1;           //RA11 PIN_12 ESP32 -> PIC32 communication
        TRISAbits.TRISA12 = 0b1;           //RA12 PIN_11 ESP32 -> PIC32 communication
        TRISAbits.TRISA0 = 0b1;            //RA0 PIN_13 UART RX

       
        Inter_Integrated_Circuit_Setup ();                                                       
        Inter_Integrated_Circuit_Enable ();                                                       
      
        //First I2C operation writing something to PCF8574 IO expander (I am getting ACK)
        
        Inter_Integrated_Circuit_Start();
        Inter_Integrated_Circuit_Write(LCD);
        Inter_Integrated_Circuit_Write(Number); 
        Inter_Integrated_Circuit_Stop();
        
        //Second I2C operation writing something to ESP32S3 (I am getting NACK)
        
        Inter_Integrated_Circuit_Start();
        Inter_Integrated_Circuit_Write(ESP32);
        Inter_Integrated_Circuit_Write(Number); 
        Inter_Integrated_Circuit_Stop();
        
            while (true){    
               
            }
        
   return (EXIT_FAILURE);}

I2C.h:

//************************************************************************** 
// INTER INTEGRATED CIRCUIT PROTOCOL HEADER FILE
//**************************************************************************

void Inter_Integrated_Circuit_Setup (void);
    
void Inter_Integrated_Circuit_Enable (void);
    
void Inter_Integrated_Circuit_Disable (void);
    
void Inter_Integrated_Circuit_State (void);
    
void Inter_Integrated_Circuit_Start (void);
    
void Inter_Integrated_Circuit_Stop (void);
    
void Inter_Integrated_Circuit_Repeated_Start (void);
    
void Inter_Integrated_Circuit_Write (uint8_t I2C_data);
    
uint8_t Inter_Integrated_Circuit_Read (void);
    
    

I2C.c:

//************************************************************************** 
// INTER INTEGRATED CIRCUIT PROTOCOL SOURCE FILE
//**************************************************************************

#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);                                                               
    while(I2C1STATbits.TRSTAT != 0);                                                           
    I2C1TRN = I2C_data;

}

uint8_t Inter_Integrated_Circuit_Read (void){
    
    uint8_t I2C_data = 0;
    Inter_Integrated_Circuit_State ();                                                         
    I2C1CONbits.RCEN = 0b1;                                                                     
    while(I2C1STATbits.RBF != 0);                                                               
    I2C_data = (I2C1RCV & 0x000000FF);                                                          
    I2C1CONbits.ACKEN = 0b1;                                                                   
    return (I2C_data);
 }

0 Answers0