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;
}
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
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
Hello christianlees,
Recommend you first refer to the I2C demo under SDK:
https://mcuxpresso.nxp.com/en/builder?hw=LPCXpresso55S06