Files
microchip-application-pec93…/Examples/i2c/i2c_slave_transceiver/src/main.c
T

211 lines
6.2 KiB
C

/**
* Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved.
*/
/** @file main.c
*
* @author Wei-Lun Hsu
* @version 0.1
* @date 2024/08/29
* @license
* @description
*/
#include <string.h>
#include "main.h"
#include "isr.h"
//=============================================================================
// Constant Definition
//=============================================================================
/**
* if defined, transfer data using interrupt mode
* if not, transfer data using polling mode
*/
#define CONFIG_USE_I2C_INTERRUPT
#define CONFIG_REMOTE_I2C_ADDR 0xAA // slave address
#define CONFIG_DATA_BUF_LEN 64 // transmit data of length
/**
* Select I2C SCL and SDA pin
*/
#define IIC_SCL_PORT GPIOA
#define IIC_SCL_PIN GPIO_Pin_00
#define IIC_SCL_AF GPIO_AF_4
#define IIC_SDA_PORT GPIOA
#define IIC_SDA_PIN GPIO_Pin_01
#define IIC_SDA_AF GPIO_AF_4
#define I2Cx I2C0
#define I2Cx_IRQn I2C0_IRQn
#if defined(CONFIG_USE_I2C_INTERRUPT)
#define CONFIG_XFER_MODE "Interrupt"
#else
#define CONFIG_XFER_MODE "Polling"
#endif
//=============================================================================
// Macro Definition
//=============================================================================
//=============================================================================
// Structure Definition
//=============================================================================
//=============================================================================
// Global Data Definition
//=============================================================================
static uint8_t g_tx_buf[CONFIG_DATA_BUF_LEN] = {0};
static uint8_t g_rx_buf[CONFIG_DATA_BUF_LEN] = {0};
static I2C_IT_HandleTypeDef g_hI2CIT = {0};
//=============================================================================
// Private Function Definition
//=============================================================================
__INTERRUPT void I2Cx_Handler(void)
{
SAVE_IRQ_CSR_CONTEXT(); // Save CSRs
I2C_Slave_IRQHandler(&g_hI2CIT);
RESTORE_IRQ_CSR_CONTEXT(); // Restore CSRs
return;
}
/**
* Configure the pin of I2C
*/
static void _Config_IO(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.GPIO_Pin = IIC_SCL_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_AF_Mode = IIC_SCL_AF;
GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;
GPIO_Init(IIC_SCL_PORT, &GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = IIC_SDA_PIN;
GPIO_InitStruct.GPIO_AF_Mode = IIC_SDA_AF;
GPIO_Init(IIC_SDA_PORT, &GPIO_InitStruct);
return;
}
//=============================================================================
// Public Function Definition
//=============================================================================
int main(void)
{
SYSCFG_ClkInitTypeDef SysClkInit = {0};
I2C_ErrTypeDef rval = I2C_Err_OK;
int data_base = 0x50;
/* Configure system clock */
SysClkInit.ClkSource = SYSCFG_ClkSrc_FreqDiv;
SysClkInit.SysClk_Div = SYSCFG_SysClkDiv8;
SYSCFG_SysClkConfig(&SysClkInit);
sys_config_systick(SYS_TICK_1_MS);
syslog_init();
info("%s %s\nI2C-Slave (%s). The local Slave-Address is 0x%02X\n",
__DATE__, __TIME__, CONFIG_XFER_MODE, (CONFIG_REMOTE_I2C_ADDR >> 1));
/* Configure the pin of I2C */
_Config_IO();
/* Configure the parameters of I2C */
I2C_InitTypeDef init = {0};
I2C_StructInit(&init);
init.Mode = I2C_Mode_SLAVE;
init.OwnAddress = CONFIG_REMOTE_I2C_ADDR >> 1;
// init.ClockDiv = I2C_CLK_Div960;
rval = I2C_Init(I2Cx, &init);
if( rval != I2C_Err_OK )
{
err("I2C init fail !\n");
}
#if defined(CONFIG_USE_I2C_INTERRUPT)
{ /* Setup Interrupt */
sys_irq_attr_t irq_attr = { .trig_mode = SYS_IRQ_TRIGGER_LEVEL, };
sys_register_IRQ(I2Cx_IRQn, I2Cx_Handler, &irq_attr);
g_hI2CIT.pHI2C = I2Cx;
}
#endif
do {
/* prepare data */
data_base++;
for(int i = 0; i < sizeof(g_tx_buf); i++)
{
g_tx_buf[i] = (data_base + i) & 0xFF;
}
log_color(SLOG_GREEN, " @ Start Transmitting...\n");
syslog_dump_mem("tx: ", (uint32_t*)&g_tx_buf, sizeof(g_tx_buf), 0);
/* IIC slave receive and transmit data */
#if defined(CONFIG_USE_I2C_INTERRUPT)
rval = I2C_Slave_Receive_IT(&g_hI2CIT, (uint8_t*)&g_rx_buf, (uint16_t)sizeof(g_rx_buf));
if( rval != I2C_Err_OK )
{
err("I2C master TX fail !\n");
break;
}
while( g_hI2CIT.XferMode != I2C_XferMode_Idle )
__NOP();
rval = I2C_Slave_Transmit_IT(&g_hI2CIT, (uint8_t*)&g_tx_buf, (uint16_t)sizeof(g_tx_buf));
if( rval != I2C_Err_OK )
{
err("I2C master RX fail !\n");
break;
}
while( g_hI2CIT.XferMode != I2C_XferMode_Idle )
__NOP();
#else
uint16_t length = 0;
length = sizeof(g_rx_buf);
memset((void*)&g_rx_buf, 0xAA, sizeof(g_rx_buf));
rval = I2C_Slave_Receive(I2Cx, (uint8_t*)&g_rx_buf, &length, I2C_BLOCKING);
if( rval != I2C_Err_OK )
{
err("I2C slave RX fail !\n");
break;
}
rval = I2C_Slave_Transmit(I2Cx, (uint8_t*)&g_tx_buf, (uint16_t)sizeof(g_tx_buf), I2C_BLOCKING);
if( rval != I2C_Err_OK )
{
err("I2C slave TX fail !\n");
break;
}
#endif
/* comparative data */
syslog_dump_mem("rx: ", (uint32_t*)&g_rx_buf, sizeof(g_rx_buf), 0);
if( !memcmp(g_tx_buf, g_rx_buf, sizeof(g_tx_buf)) )
msg("done~~ \n\n");
else
{
err("Data is NOT match !\n");
break;
}
} while(1);
while(1);
return 0;
}