Untitled

 avatar
unknown
plain_text
24 days ago
3.8 kB
7
Indexable
#include "hal_data.h"

// Configuration
#define I2C_FAST_MODE_PLUS_SPEED    1000000  // 1 MHz
#define I2C_DEFAULT_DMA_THRESHOLD   32       // Default DMA threshold
#define I2C_RETRY_COUNT             3        // Retry attempts for errors

// State Variables
static volatile bool i2c_transfer_complete = false;
static volatile bool i2c_transfer_error = false;
static uint32_t dma_threshold = I2C_DEFAULT_DMA_THRESHOLD;

// Function Prototypes
static void i2c_init(void);
static fsp_err_t i2c_transfer(uint8_t device_addr, uint8_t *data, uint32_t length, bool read, bool use_dma);
static void i2c_bus_recovery(void);
static void i2c_callback(i2c_master_callback_args_t *p_args);

// User API
fsp_err_t i2c_write(uint8_t device_addr, uint8_t *data, uint32_t length, bool use_dma);
fsp_err_t i2c_read(uint8_t device_addr, uint8_t *data, uint32_t length, bool use_dma);

// Initialization
static void i2c_init(void)
{
    fsp_err_t err;

    // Open I2C driver
    err = R_IIC_MASTER_Open(&g_i2c_master0, &g_i2c_master0_cfg);
    if (err != FSP_SUCCESS)
    {
        __BKPT();  // Debug breakpoint
    }

    // Enable Fast Mode Plus
    R_IIC_MASTER_SetSpeed(&g_i2c_master0, I2C_FAST_MODE_PLUS_SPEED);
}

// Core Transfer Logic
static fsp_err_t i2c_transfer(uint8_t device_addr, uint8_t *data, uint32_t length, bool read, bool use_dma)
{
    fsp_err_t err;
    int retries = I2C_RETRY_COUNT;

    // Retry logic
    while (retries-- > 0)
    {
        i2c_transfer_complete = false;
        i2c_transfer_error = false;

        // DMA or interrupt-based transfer
        if (use_dma && length > dma_threshold)
        {
            if (read)
                err = R_IIC_MASTER_Read(&g_i2c_master0, data, length, device_addr, false);
            else
                err = R_IIC_MASTER_Write(&g_i2c_master0, data, length, device_addr, false);
        }
        else
        {
            if (read)
                err = R_IIC_MASTER_Read(&g_i2c_master0, data, length, device_addr, false);
            else
                err = R_IIC_MASTER_Write(&g_i2c_master0, data, length, device_addr, false);
        }

        if (err != FSP_SUCCESS)
        {
            i2c_bus_recovery();
            continue;  // Retry
        }

        // Wait for ISR to complete transfer
        while (!i2c_transfer_complete && !i2c_transfer_error)
        {
            __WFI();  // Wait for interrupt
        }

        // Check if transfer was successful
        if (!i2c_transfer_error)
        {
            return FSP_SUCCESS;
        }
    }

    return FSP_ERR_ABORTED;  // Return error after retries
}

// Bus Recovery
static void i2c_bus_recovery(void)
{
    R_IIC_MASTER_BusRecovery(&g_i2c_master0);
}

// ISR Callback
static void i2c_callback(i2c_master_callback_args_t *p_args)
{
    if (p_args->event == I2C_MASTER_EVENT_TRANSFER_COMPLETE)
    {
        i2c_transfer_complete = true;
    }
    else if (p_args->event == I2C_MASTER_EVENT_ABORTED)
    {
        i2c_transfer_error = true;
    }
}

// Public Write Function
fsp_err_t i2c_write(uint8_t device_addr, uint8_t *data, uint32_t length, bool use_dma)
{
    return i2c_transfer(device_addr, data, length, false, use_dma);
}

// Public Read Function
fsp_err_t i2c_read(uint8_t device_addr, uint8_t *data, uint32_t length, bool use_dma)
{
    return i2c_transfer(device_addr, data, length, true, use_dma);
}

// Main
int main(void)
{
    uint8_t buffer[64];
    fsp_err_t err;

    // Initialize I2C
    i2c_init();

    // Example Write
    buffer[0] = 0xAA;
    err = i2c_write(0x50, buffer, 1, false);
    if (err != FSP_SUCCESS)
    {
        // Handle write error
    }

    // Example Read
    err = i2c_read(0x50, buffer, 10, false);
    if (err != FSP_SUCCESS)
    {
        // Handle read error
    }

    while (1)
    {
        // Application loop
    }
}
Leave a Comment