Configure S32k322 LPI2C channel 0 in master mode

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

Configure S32k322 LPI2C channel 0 in master mode

9,726 次查看
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 项奖励
回复
20 回复数

9,704 次查看
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 项奖励
回复

9,658 次查看
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 项奖励
回复

9,633 次查看
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 项奖励
回复

9,592 次查看
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 项奖励
回复

9,577 次查看
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 项奖励
回复

9,534 次查看
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 项奖励
回复

9,493 次查看
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 项奖励
回复

9,417 次查看
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,368 次查看
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 项奖励
回复

9,319 次查看
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 项奖励
回复

9,150 次查看
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 项奖励
回复

9,134 次查看
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

9,059 次查看
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 项奖励
回复

9,001 次查看
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 项奖励
回复

8,625 次查看
pratik_a
Contributor III

Hi @Julián_AragónM ,

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

 

Regards,

Pratik

0 项奖励
回复

8,545 次查看
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 项奖励
回复

8,520 次查看
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 项奖励
回复

8,461 次查看
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 项奖励
回复

8,981 次查看
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 项奖励
回复

8,819 次查看
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 项奖励
回复