xmclib/XMCLib/examples/XMC4500_series/I2C/I2C_TRANSFER/main.c
2024-10-17 17:09:59 +02:00

178 lines
5.5 KiB
C

/*
* Copyright (C) 2014 Infineon Technologies AG. All rights reserved.
*
* Infineon Technologies AG (Infineon) is supplying this software for use with
* Infineon's microcontrollers.
* This file can be freely distributed within development tools that are
* supporting such microcontrollers.
*
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* INFINEON SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL,
* OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
*/
/**
* @file
* @date 06 September, 2016
* @version 1.0.4
*
* @brief I2C demo example
*
* For this demo either the COM or the HMI satellite boards for the XMC45 CPU board are required.
* It communicates with the IO expander found in the mentioned satellite boards.
* Attention: The address of the IO expander is different on the two satellite boards
* The demo implements a binary counter using the LEDs attached to the IO expander.
*
* History <br>
*
* Version 1.0.0 Initial
* Version 1.0.1 Adapted to the last llds
* Version 1.0.2 Changed XMC_GPIO_SetMode() to XMC_GPIO_Init() for code clarity reasons
* Version 1.0.4 Added ACT_PCA9502_ADDRESS
*/
#include <xmc_gpio.h>
#include <xmc_i2c.h>
/* IO expander address on COM board */
#define COM_PCA9502_ADDRESS (0x98)
/* IO expander address on HMI board */
#define HMI_PCA9502_ADDRESS (0x9A)
/* IO expander address on AUT_ISO board */
#define ACT_PCA9502_ADDRESS (0x90)
#define IO_EXPANDER_ADDRESS HMI_PCA9502_ADDRESS
typedef enum PCA9502_REGADDR {
IO_DIR = 0xA << 3,
IO_STATE = 0xB << 3,
IO_INTE = 0xC << 3,
IO_CTRL = 0xE << 3
} PCA9502_REGADDR_t;
#define SDA_PIN P2_14
#define SCL_PIN P5_8
XMC_GPIO_CONFIG_t i2c_sda =
{
.mode = XMC_GPIO_MODE_OUTPUT_OPEN_DRAIN_ALT2,
.output_strength = XMC_GPIO_OUTPUT_STRENGTH_MEDIUM
};
XMC_GPIO_CONFIG_t i2c_scl =
{
.mode = XMC_GPIO_MODE_OUTPUT_OPEN_DRAIN_ALT2,
.output_strength = XMC_GPIO_OUTPUT_STRENGTH_MEDIUM
};
XMC_I2C_CH_CONFIG_t i2c_cfg =
{
.baudrate = 100000U,
};
void delay(uint32_t counter);
int main(void)
{
uint8_t counter = 0;
uint8_t io_state1 = 0;
uint8_t received_data;
XMC_I2C_CH_Init(XMC_I2C1_CH0, &i2c_cfg);
XMC_I2C_CH_SetInputSource(XMC_I2C1_CH0, XMC_I2C_CH_INPUT_SDA, USIC1_C0_DX0_P2_14);
XMC_I2C_CH_SetInputSource(XMC_I2C1_CH0, XMC_I2C_CH_INPUT_SCL, USIC1_C0_DX1_P5_8);
XMC_I2C_CH_Start(XMC_I2C1_CH0);
XMC_GPIO_Init(SCL_PIN, &i2c_scl);
XMC_GPIO_Init(SDA_PIN, &i2c_sda);
XMC_I2C_CH_MasterStart(XMC_I2C1_CH0, IO_EXPANDER_ADDRESS, XMC_I2C_CH_CMD_WRITE);
while((XMC_I2C_CH_GetStatusFlag(XMC_I2C1_CH0) & XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED) == 0U)
{
/* wait for ACK */
}
XMC_I2C_CH_ClearStatusFlag(XMC_I2C1_CH0, XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED);
XMC_I2C_CH_MasterTransmit(XMC_I2C1_CH0, IO_DIR);
while((XMC_I2C_CH_GetStatusFlag(XMC_I2C1_CH0) & XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED) == 0U)
{
/* wait for ACK */
}
XMC_I2C_CH_ClearStatusFlag(XMC_I2C1_CH0, XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED);
XMC_I2C_CH_MasterTransmit(XMC_I2C1_CH0, 0xffU);
while((XMC_I2C_CH_GetStatusFlag(XMC_I2C1_CH0) & XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED) == 0U)
{
/* wait for ACK */
}
XMC_I2C_CH_ClearStatusFlag(XMC_I2C1_CH0, XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED);
while(counter < 255)
{
io_state1 = ~counter;
counter++;
XMC_I2C_CH_MasterRepeatedStart(XMC_I2C1_CH0, IO_EXPANDER_ADDRESS, XMC_I2C_CH_CMD_WRITE);
while((XMC_I2C_CH_GetStatusFlag(XMC_I2C1_CH0) & XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED) == 0U)
{
/* wait for ACK */
}
XMC_I2C_CH_ClearStatusFlag(XMC_I2C1_CH0, XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED);
XMC_I2C_CH_MasterTransmit(XMC_I2C1_CH0, IO_STATE);
while((XMC_I2C_CH_GetStatusFlag(XMC_I2C1_CH0) & XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED) == 0U)
{
/* wait for ACK */
}
XMC_I2C_CH_ClearStatusFlag(XMC_I2C1_CH0, XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED);
XMC_I2C_CH_MasterTransmit(XMC_I2C1_CH0, io_state1);
while((XMC_I2C_CH_GetStatusFlag(XMC_I2C1_CH0) & XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED) == 0U)
{
/* wait for ACK */
}
XMC_I2C_CH_ClearStatusFlag(XMC_I2C1_CH0, XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED);
XMC_I2C_CH_MasterRepeatedStart(XMC_I2C1_CH0, IO_EXPANDER_ADDRESS, XMC_I2C_CH_CMD_READ);
while((XMC_I2C_CH_GetStatusFlag(XMC_I2C1_CH0) & XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED) == 0U)
{
/* wait for ACK */
}
XMC_I2C_CH_ClearStatusFlag(XMC_I2C1_CH0, XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED);
XMC_I2C_CH_MasterReceiveNack(XMC_I2C1_CH0);
while((XMC_I2C_CH_GetStatusFlag(XMC_I2C1_CH0) & (XMC_I2C_CH_STATUS_FLAG_RECEIVE_INDICATION |
XMC_I2C_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION)) == 0U)
{
/* wait for ACK */
}
XMC_I2C_CH_ClearStatusFlag(XMC_I2C1_CH0, XMC_I2C_CH_STATUS_FLAG_RECEIVE_INDICATION |
XMC_I2C_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
received_data = XMC_I2C_CH_GetReceivedData(XMC_I2C1_CH0);
if(io_state1 != received_data)
{
while(1);
}
/* Delay to make visible the change */
delay(0xfffff);
}
XMC_I2C_CH_MasterStop(XMC_I2C1_CH0);
while(1);
}
void delay(uint32_t counter)
{
volatile uint32_t cnt = counter;
while(--cnt);
}