Configure S32k322 LPI2C channel 0 in master mode

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Configure S32k322 LPI2C channel 0 in master mode

9,567 Views
pratik_a
Contributor III

Hi,

I'm trying to configure LPI2C_0 in master mode. I tried to look out for the examples in the Autosar RTD example section, but there the I2C pins are configured using Flex IO.

I'm trying to interface DS3231 RTC with the controller using LPI2C channel 0 in master mode.

Any help is appreciated,

Regards,

Pratik

0 Kudos
Reply
20 Replies

9,545 Views
Julián_AragónM
NXP TechSupport
NXP TechSupport

Hi @pratik_a,

You can use the following post as guidance: Example S32K312 I2C Transmit & Receive Using DMA DS3.5 RTD300 - NXP Community

It configures two instances for LPI2C as master-slave. You can see the transmission by measuring the SDA pin:

Julin_AragnM_0-1712858328099.png

Best regards,
Julián

0 Kudos
Reply

9,499 Views
pratik_a
Contributor III

Hi @Julián_AragónM 

The example portrays I2C configuration using the non-autosar method whereas I want to go ahead with the Autosar way of implementing I2C communications. 

Please help.

Regards,

Pratik

0 Kudos
Reply

9,474 Views
Julián_AragónM
NXP TechSupport
NXP TechSupport

Hi @pratik_a,

The I2c_Example_S32K344 uses one instance as LPI2C and another one as I2C_FlexIO. You can create a new project for the S32K322 derivative and port over the example, changing it so it uses two I2C instances and changing the respective pins, as well as disabling FlexIO for the I2C module:

Julin_AragnM_0-1713470567467.png

Julin_AragnM_1-1713470647102.png

Julin_AragnM_2-1713470657782.png

Julin_AragnM_3-1713470666712.png

Julin_AragnM_4-1713470673298.png

I have made a quick test with the S32K344 EVB:

Julin_AragnM_5-1713470765595.png

 

Best regards,
Julián

 

0 Kudos
Reply

9,433 Views
pratik_a
Contributor III

Hi @Julián_AragónM ,

I have connected DS3231 RTC IC as a slave to the LPI2C0 of S32K322. So, I'm trying to configure LPI2C0 in the master mode. As instructed by you in the above post I disabled the flex IO and configured the LPI2C0 in the master mode, but I'm getting an error for baud rate as can be seen in the image.

Kindly help.


Regards,

Pratik

0 Kudos
Reply

9,418 Views
Julián_AragónM
NXP TechSupport
NXP TechSupport

Hi @pratik_a,

Modify the value of I2c Clock High Period (CLKHI) and I2c Clock Low Period (CLKLO). The I2c Baud Rate will be automatically calculated based on your input value and will be displayed there. This is because of the I2C mode you are using (LPI2C_STANDARD_MODE) the upper limit has been exceeded. 

You can find how the timing parameters are calculated from Table 440 from the S32K3xx Reference Manual:

Julin_AragnM_0-1713806482624.png

Best regards,
Julián

0 Kudos
Reply

9,375 Views
pratik_a
Contributor III

Hi @Julián_AragónM ,

Thank you for providing continuous support. So, I changed the parameters of CLKHI and CLKLO as per the reference manual.

pratik_a_0-1713867193356.png

For standard mode and 8MHz core clock, I set the parameters as seen in the image above, but I'm getting a different baud rate as compared to what is mentioned in the manual. I'm trying to achieve 100Kbps baud rate.

pratik_a_1-1713867441367.png

Also, I'm getting an error when I try to compile the code. I have configured only LPI2C0 and disabled flex IO. 

 
/**
*   @file main.c
*
*   @addtogroup main_module main module documentation
*   @{
*/
 
/* Including necessary configuration files. */
#include "Mcal.h"
#include "Mcu.h"
#include "Platform.h"
#include "Port.h"
#include "CDD_I2c.h"
 
 
#define TRANSFER_SIZE 8U
 
I2c_DataType rxBufferSlave[TRANSFER_SIZE] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
I2c_DataType rxBufferMaster[TRANSFER_SIZE] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
I2c_DataType txBuffer[TRANSFER_SIZE] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7};
 
I2c_RequestType pRequest[2] =
{
    /* Slave address */ /*10 bit address*/ /*high speed */ /* expect Nack */ /*repeated start */ /*buffer size */ /*Data direction */ /*Buffer*/
{   0x32,               FALSE,             FALSE,          FALSE,            FALSE,              8U,              I2C_SEND_DATA,      txBuffer},
{   0x32,               FALSE,             FALSE,          FALSE,            FALSE,              8U,              I2C_RECEIVE_DATA,      rxBufferMaster}
 
};
 
/* User includes */
void I2c_Callback(uint8 u8Event, uint8 u8Channel)
{
    switch(u8Event)
    {
case I2C_EVENT_RX_REQ_SLAVE:
I2c_PrepareSlaveBuffer((uint8)u8Channel, TRANSFER_SIZE, rxBufferSlave);
break;
 
case I2C_EVENT_TX_REQ_SLAVE:
I2c_PrepareSlaveBuffer((uint8)u8Channel, TRANSFER_SIZE, txBuffer);
break;
        default:
            (void) u8Channel;
    }
}
 
/*!
  \brief The main function for the project.
  \details The startup initialization sequence is the following:
 * - startup asm routine
 * - main()
*/
int main(void)
{
    uint8 i;
    volatile uint32 timeout = 0xFFFF;
    boolean checkOk = TRUE;
    volatile I2c_StatusType status;
 
/* Init system clock */
Mcu_Init(NULL_PTR);
 
/* Initialize the clock tree and apply PLL as system clock */
Mcu_InitClock(McuClockSettingConfig_0);
while (MCU_PLL_LOCKED != Mcu_GetPllStatus())
{
  /* Busy wait until the System PLL is locked */
}
 
Mcu_DistributePllClock();
Mcu_SetMode(McuModeSettingConf_0);
 
/* Initialize Port driver */
Port_Init(NULL_PTR);
 
/* Initialize Interrupt */
Platform_Init(NULL_PTR);
 
/* Init i2c instances */
I2c_Init(NULL_PTR);
/* Init i2c instances */
I2c_Init(NULL_PTR);
 
/* Slave recieve data */
I2c_StartListening(1U);
 
/* Master send data */
I2c_AsyncTransmit(0U, &pRequest[0]);
/* Wait until master is ready */
while (((status = I2c_GetStatus(0U)) == I2C_CH_SEND) && (timeout > 0))
{
timeout--;
}
 
/* Wait until slave is ready */
while (((status = I2c_GetStatus(1U)) == I2C_CH_RECEIVE) && (timeout > 0))
{
timeout--;
}
 
/* Slave recieve data */
I2c_StartListening(1U);
 
/* Master send data */
I2c_AsyncTransmit(0U, &pRequest[1]);
 
/* Wait until master is ready */
while (((status = I2c_GetStatus(0U)) == I2C_CH_RECEIVE) && (timeout > 0))
{
timeout--;
}
 
/* Wait until slave is ready */
while (((status = I2c_GetStatus(1U)) == I2C_CH_SEND) && (timeout > 0))
{
timeout--;
}
 
/* Verify data received */
for (i = 0; i < TRANSFER_SIZE; i ++)
{
if( txBuffer[i] != rxBufferMaster[i])
{
checkOk = FALSE;
}
}
 
    return 0;
}
 
/** @} */

THe error i'm facing is,

undefined reference to `LPI2C0_Master_IRQHandler'

I have attached a few images for your reference.

Kindly help,

Regards,

Pratik

0 Kudos
Reply

9,334 Views
pratik_a
Contributor III

Hi @Julián_AragónM ,

I'm still stuck with the following error, can you please check what's going wrong there?

undefined reference to `LPI2C0_Master_IRQHandler'

 

Regards,

Pratik

0 Kudos
Reply

9,258 Views
Julián_AragónM
NXP TechSupport
NXP TechSupport

Hi @pratik_a,

The LPI2C handler is "LPI2C0_Master_Slave_IRQHandler", please try configuring this in the Interrupt Controller:

Julin_AragnM_0-1713997976830.png

Best regards,
Julián

9,209 Views
pratik_a
Contributor III

Hi @Julián_AragónM 

Thank you for your continuous support. I'm grateful for your help.

I tried renaming the handler's name and the code compiled successfully, but I'm faced with a new problem. I'm using a PE micro multilink for debugging and I have placed two breakpoints at

Port_Init(NULL_PTR); and

Platform_Init(NULL_PTR);

so, whenever I press resume after "Port_Init(NULL_PTR);" my debugging terminates, and console gives following output.

P&E Semihosting Console

Connection closed by the GDB server.

I'm attaching my code for your reference.

 
 
/**
*   @file main.c
*
*   @addtogroup main_module main module documentation
*   @{
*/
 
/* Including necessary configuration files. */
#include "Mcal.h"
#include "Mcu.h"
#include "Platform.h"
#include "Port.h"
#include "CDD_I2c.h"
 
 
#define TRANSFER_SIZE 8U
 
I2c_DataType rxBufferSlave[TRANSFER_SIZE] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
I2c_DataType rxBufferMaster[TRANSFER_SIZE] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
I2c_DataType txBuffer[TRANSFER_SIZE] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7};
 
I2c_RequestType pRequest[2] =
{
    /* Slave address */ /*10 bit address*/ /*high speed */ /* expect Nack */ /*repeated start */ /*buffer size */ /*Data direction */ /*Buffer*/
{   0x32,               FALSE,             FALSE,          FALSE,            FALSE,              8U,              I2C_SEND_DATA,      txBuffer},
{   0x32,               FALSE,             FALSE,          FALSE,            FALSE,              8U,              I2C_RECEIVE_DATA,      rxBufferMaster}
 
};
 
/* User includes */
void I2c_Callback(uint8 u8Event, uint8 u8Channel)
{
    switch(u8Event)
    {
case I2C_EVENT_RX_REQ_SLAVE:
I2c_PrepareSlaveBuffer((uint8)u8Channel, TRANSFER_SIZE, rxBufferSlave);
break;
 
case I2C_EVENT_TX_REQ_SLAVE:
I2c_PrepareSlaveBuffer((uint8)u8Channel, TRANSFER_SIZE, txBuffer);
break;
        default:
            (void) u8Channel;
    }
}
 
/*!
  \brief The main function for the project.
  \details The startup initialization sequence is the following:
 * - startup asm routine
 * - main()
*/
int main(void)
{
    uint8 i;
    volatile uint32 timeout = 0xFFFF;
    boolean checkOk = TRUE;
    volatile I2c_StatusType status;
 
/* Init system clock */
Mcu_Init(NULL_PTR);
 
/* Initialize the clock tree and apply PLL as system clock */
Mcu_InitClock(McuClockSettingConfig_0);
#if (STD_OFF == MCU_NO_PLL)
while (MCU_PLL_LOCKED != Mcu_GetPllStatus())
{
  /* Busy wait until the System PLL is locked */
}
Mcu_DistributePllClock();
#endif
 
Mcu_SetMode(McuModeSettingConf_0);
 
/* Initialize Port driver */
Port_Init(NULL_PTR);
 
/* Initialize Interrupt */
Platform_Init(NULL_PTR);
 
/* Init i2c instances */
I2c_Init(NULL_PTR);
 
for(;;){
/* Master send data */
I2c_AsyncTransmit(0U, &pRequest[0]);
/* Wait until master is ready */
while (((status = I2c_GetStatus(0U)) == I2C_CH_SEND) && (timeout > 0))
{
timeout--;
}
}
    return 0;
}
 
/** @} */

 

 

0 Kudos
Reply

9,160 Views
Julián_AragónM
NXP TechSupport
NXP TechSupport

Hi @pratik_a,

Could you share your Port configuration from the Peripherals tab in Config Tools? Could you also confirm the port pins are configured correctly?

Julin_AragnM_0-1714173043199.png

It would also help if you stepped into the Port_Init function and locate where the program stops.

Best regards,
Julián

0 Kudos
Reply

8,991 Views
pratik_a
Contributor III

Hi @Julián_AragónM 

I have attached the port configuration screenshots.

Also, I stepped into the function and found that the program terminates in the if loop in the program below.

pratik_a_0-1714408066368.png

The code is from function,

static inline void Port_Ipw_Init_UnusedPins(const Port_ConfigType * pConfigPtr)

from file Port_Ipw.c

Regards,

Pratik

 

0 Kudos
Reply

8,975 Views
Julián_AragónM
NXP TechSupport
NXP TechSupport

Hi @pratik_a,

There is an important note inside RTD_PORT_UM:

Julin_AragnM_0-1714422453278.png

You can copy over the configuration from an already existing example:

Julin_AragnM_1-1714422482254.png

This will hopefully fix this issue.

Best regards,
Julián

8,900 Views
pratik_a
Contributor III

Hi @Julián_AragónM 

I should have better read the document, pardon my questions. 

Well, that did solve the debugging issue. I'm still unable to get the I2C working. I checked the signals using a logic analyzer.

What am I missing out on?

/**
*   @file main.c
*
*   @addtogroup main_module main module documentation
*   @{
*/
 
/* Including necessary configuration files. */
#include "Mcal.h"
#include "Mcu.h"
#include "Platform.h"
#include "Port.h"
#include "CDD_I2c.h"
 
 
#define TRANSFER_SIZE 8U
 
I2c_DataType rxBufferSlave[TRANSFER_SIZE] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
I2c_DataType rxBufferMaster[TRANSFER_SIZE] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
I2c_DataType txBuffer[TRANSFER_SIZE] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7};
 
I2c_RequestType pRequest[2] =
{
    /* Slave address */ /*10 bit address*/ /*high speed */ /* expect Nack */ /*repeated start */ /*buffer size */ /*Data direction */ /*Buffer*/
{   0x68,               FALSE,             FALSE,          FALSE,            FALSE,              8U,              I2C_SEND_DATA,      txBuffer},
{   0x68,               FALSE,             FALSE,          FALSE,            FALSE,              8U,              I2C_RECEIVE_DATA,      rxBufferMaster}
 
};
 
/* User includes */
void I2c_Callback(uint8 u8Event, uint8 u8Channel)
{
    switch(u8Event)
    {
case I2C_EVENT_RX_REQ_SLAVE:
I2c_PrepareSlaveBuffer((uint8)u8Channel, TRANSFER_SIZE, rxBufferSlave);
break;
 
case I2C_EVENT_TX_REQ_SLAVE:
I2c_PrepareSlaveBuffer((uint8)u8Channel, TRANSFER_SIZE, txBuffer);
break;
        default:
            (void) u8Channel;
    }
}
 
/*!
  \brief The main function for the project.
  \details The startup initialization sequence is the following:
 * - startup asm routine
 * - main()
*/
int main(void)
{
    uint8 i;
    volatile uint32 timeout = 0xFFFF;
    boolean checkOk = TRUE;
    volatile I2c_StatusType status;
 
/* Init system clock */
Mcu_Init(NULL_PTR);
 
/* Initialize the clock tree and apply PLL as system clock */
Mcu_InitClock(McuClockSettingConfig_0);
#if (STD_OFF == MCU_NO_PLL)
while (MCU_PLL_LOCKED != Mcu_GetPllStatus())
{
  /* Busy wait until the System PLL is locked */
}
Mcu_DistributePllClock();
#endif
 
Mcu_SetMode(McuModeSettingConf_0);
 
/* Initialize Port driver */
Port_Init(NULL_PTR);
 
/* Initialize Interrupt */
Platform_Init(NULL_PTR);
 
/* Init i2c instances */
  I2c_Init(NULL_PTR);
 
for(;;){
/* Master send data */
I2c_AsyncTransmit(0U, &pRequest[0]);
/* Wait until master is ready */
while (((status = I2c_GetStatus(0U)) == I2C_CH_SEND) && (timeout > 0))
{
timeout--;
}
}
    return 0;
}
 
/** @} */
 
Appreciate your continuous help.
Regards, 
Pratik

 

 

0 Kudos
Reply

8,842 Views
Julián_AragónM
NXP TechSupport
NXP TechSupport

Hi @pratik_a,

What exactly is the issue? When using the analyzer were you able to see the transmitted data? If yes, is the slave not receiving the data?

 

0 Kudos
Reply

8,466 Views
pratik_a
Contributor III

Hi @Julián_AragónM ,

I'm still stuck with the problem; any help is appreciated.

 

Regards,

Pratik

0 Kudos
Reply

8,386 Views
Julián_AragónM
NXP TechSupport
NXP TechSupport

Hi @pratik_a,

Sorry for the delay. Looking into your slave's datasheet, it seems the SCL line supports up to Fast-mode (400kbit/s). Could this be the issue? Please test with this baudrate configuration.

Julin_AragnM_0-1715120917171.png

Best regards,
Julián

0 Kudos
Reply

8,361 Views
pratik_a
Contributor III

Hi @Julián_AragónM 

Thank you for your continuous support.

I checked the datasheet of DS 3231 it supports 100kHz in normal mode and up to 400kHz in fast mode. I also tried adjusting the baud rate by doing the following settings,

pratik_a_0-1715168702608.png

I still don't get any output, not even on the clock line. 

Can you check my code once for any errors.

Regards,

Pratik

 

 

0 Kudos
Reply

8,302 Views
Julián_AragónM
NXP TechSupport
NXP TechSupport

Hi @pratik_a,

Sorry, it seems everything is correct when I checked your code. I'm not sure why there are no line generation, could you test another I2C instance or other pins to test HW as well? 

Best regards,
Julián

0 Kudos
Reply

8,822 Views
pratik_a
Contributor III

Hi @Julián_AragónM 

I'm unable to get any signals on SDA or the SCL line when I connect the logic analyzer to it.

I have done all the settings according to the tutorial. Please go through my ode if I have done anything wrong,

 

0 Kudos
Reply

8,660 Views
pratik_a
Contributor III

Hi @Julián_AragónM 

I tried debugging the I2c_Init(NULL_PTR); function and when I step in I believe CoreId = (uint8) I2c_GetCoreID(); function returns 0. I'm using core 1 of the NXP S32K322 and my slave is a DS3231 RTC chip with a slave address 0x68. Let me know if that is the issue or if I'm missing out on something else.

 

Regards,

Pratik

0 Kudos
Reply