LPC55 Flexcomm5 I2C

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

LPC55 Flexcomm5 I2C

854 Views
christianlees
Contributor III

For some reason I can't get an I2C interface to work on Flexcomm5 on an LPC5506.

I have double checked my code, most of it was generated by the pin and peripheral tools inside MCUXpresso.  The SDA and SCL lines never get driven low.  I have verified my PCB by changing them to GPIO and making sure they can go low.

I have also tried using the polling method with the same results, no action on the SDA and SCL lines.  I have 10k pull up resistors.

Any help will be appreciated

From perhipherals.c

 **********************************************************************************************************************/
/* clang-format off */
/* TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
instance:
- name: 'I2C'
- type: 'flexcomm_i2c'
- mode: 'I2C_Transfer'
- custom_name_enabled: 'true'
- type_id: 'flexcomm_i2c_567d1a9d97c12e5d39b00259c3436dc4'
- functional_group: 'BOARD_InitPeripherals'
- peripheral: 'FLEXCOMM5'
- config_sets:
  - transferCfg:
    - transfer:
      - init_callback: 'true'
      - callback_fcn: 'I2C_callback'
      - user_data: ''
      - init_transfer: 'false'
      - master_transfer_cfg:
        - flags: 'kI2C_TransferDefaultFlag'
        - slaveAddress: '0'
        - direction: 'kI2C_Write'
        - subaddressSize: '0'
        - subaddress: '0'
        - dataSize: '32'
  - fsl_i2c:
    - i2c_mode: 'kI2C_Master'
    - clockSource: 'FXCOMFunctionClock'
    - clockSourceFreq: 'BOARD_BootClockFRO12M'
    - i2c_master_config:
      - enableMaster: 'true'
      - baudRate_Bps: '100000'
      - enableTimeout: 'true'
    - interrupt_priority:
      - IRQn: 'FLEXCOMM5_IRQn'
      - enable_priority: 'false'
      - priority: '5'
 * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/
/* clang-format on */
const i2c_master_config_t I2C_config = {
  .enableMaster = true,
  .baudRate_Bps = 100000UL,
  .enableTimeout = true
};
i2c_master_handle_t I2C_handle;

static void I2C_init(void) {
  RESET_PeripheralReset( kFC5_RST_SHIFT_RSTn);
  /* Initialization function */
  I2C_MasterInit(I2C_PERIPHERAL, &I2C_config, I2C_CLOCK_SOURCE);
  memset(&I2C_handle, 0, sizeof(I2C_handle));
  I2C_MasterTransferCreateHandle(I2C_PERIPHERAL, &I2C_handle, I2C_callback, NULL);
}

Peripherals.h

/* BOARD_InitPeripherals defines for FLEXCOMM5 */
/* Definition of peripheral ID */
#define I2C_PERIPHERAL ((I2C_Type *)FLEXCOMM5)
/* Definition of the clock source frequency */
#define I2C_CLOCK_SOURCE 8000000UL
/* I2C interrupt vector ID (number). */
#define I2C_FLEXCOMM_IRQN FLEXCOMM5_IRQn

 

I2C routines

uint8_t completion_flag;
uint8_t nak_flag;

void I2C_callback(I2C_Type *base, i2c_master_handle_t *handle, status_t status, void *userData)
{
    /* Signal transfer success when received success status. */
    if (status == kStatus_Success)
    {
        completion_flag = true;
    }
    /* Signal transfer success when received success status. */
    if ((status == kStatus_I2C_Nak))
    {
        nak_flag = true;
    }
}

uint8_t i2c_wait(int timeout)
{
	uint32_t start_time = tick_counter;
	while(1)
	{

		if(start_time + timeout > start_time)
		{
			if((start_time + timeout) < tick_counter)
				break;
		}
		else
		{
			if((start_time + timeout) < tick_counter && tick_counter < (4294967295 - timeout))
				break;
		}

		if(completion_flag)
			return 0;
	}

	return 1;
}

uint8_t i2c_write(uint8_t addr, uint16_t sub_addr, uint8_t sub_addr_len, uint8_t *d, uint8_t len, int timeout)
{
	i2c_master_transfer_t i2c_transfer;
	memset(&i2c_transfer, 0, sizeof(i2c_transfer));
	i2c_transfer.slaveAddress = addr;
	i2c_transfer.direction = kI2C_Write;
	i2c_transfer.subaddress = sub_addr;
	i2c_transfer.subaddressSize = sub_addr_len;
	i2c_transfer.data = d;
	i2c_transfer.dataSize = len;
	i2c_transfer.flags = kI2C_TransferDefaultFlag;

	completion_flag = false;
	nak_flag = false;
	I2C_MasterTransferNonBlocking(I2C_PERIPHERAL, &I2C_handle, &i2c_transfer);

	if(i2c_wait(timeout))
		return 1;
	else
		return 0;
}


uint8_t i2c_read(uint8_t addr, uint16_t sub_addr, uint8_t sub_addr_len, uint8_t *d, uint8_t len, int timeout)
{
	i2c_master_transfer_t i2c_transfer;
	memset(&i2c_transfer, 0, sizeof(i2c_transfer));
	i2c_transfer.slaveAddress = addr;
	i2c_transfer.direction = kI2C_Read;
	i2c_transfer.subaddress = sub_addr;
	i2c_transfer.subaddressSize = sub_addr_len;
	i2c_transfer.data = d;
	i2c_transfer.dataSize = len;
	i2c_transfer.flags = kI2C_TransferDefaultFlag;

	completion_flag = false;
	nak_flag = false;
	I2C_MasterTransferNonBlocking(I2C_PERIPHERAL, &I2C_handle, &i2c_transfer);

	if(i2c_wait(timeout))
		return 1;
	else
		return 0;
}

 

Labels (1)
0 Kudos
3 Replies

835 Views
christianlees
Contributor III

Alice,

I did that and it worked.  But if I start a new project, use the supplies gui tools for setting the clocks and pins and then use the simplest I2C code it still doesn't work.   A solution is to not use the GUI tools for this part of my code

 

0 Kudos

825 Views
Alice_Yang
NXP TechSupport
NXP TechSupport

Hello christianlees,

The MCUXpressso config GUI not generate all the related code, you can compare the generated code with demo project code, check which code you need to add .

 

BR

Alice

0 Kudos

844 Views
Alice_Yang
NXP TechSupport
NXP TechSupport

Hello christianlees,

Recommend you first refer to the I2C demo under SDK:

https://mcuxpresso.nxp.com/en/builder?hw=LPCXpresso55S06  

 

Alice_Yang_0-1622448039750.png

 

0 Kudos