/************************************************************************************************/
/**
* @file               i2c_bsp.c
* @author             MCU Ecosystem Development Team
* @brief              I2C BSP驱动函数，实现I2C主模式通信。
*
*
**************************************************************************************************
* @attention
* Copyright (c) CEC Huada Electronic Design Co.,Ltd. All rights reserved.
*
**************************************************************************************************
*/

/*------------------------------------------includes--------------------------------------------*/
#include "i2c_bsp.h"

/*------------------------------------------variables-------------------------------------------*/
uint8_t g_tx_buffer[DATA_LENGTH] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
uint8_t g_rx_buffer[DATA_LENGTH];
/* DMA搬运结束标志，搬运结束中断服务程序中将其置位 */
__IO uint32_t g_ch0_complete = 0;
__IO uint32_t g_ch1_complete = 0;

/*------------------------------------------functions-------------------------------------------*/
/**
* @brief  DMA通道0中断服务函数
* @retval 无
*/
void DMA_Channel0_IRQHandler(void)
{
    /* DMA传输完成中断服务 */
    if((std_dma_get_interrupt_enable(DMA_CHANNEL_0, DMA_INTERRUPT_TF)) && (std_dma_get_flag(DMA_FLAG_TF0)))
    {
        std_dma_interrupt_disable(DMA_CHANNEL_0, DMA_INTERRUPT_TF);
        /* 清除DMA通道0所有标志位 */
        std_dma_clear_flag(DMA_CLEAR_G0);
        
        /* 根据应用需求，添加不同应用程序代码 */
        g_ch0_complete = 1;
    }
    
    /* DMA传输错误中断服务 */
    if((std_dma_get_interrupt_enable(DMA_CHANNEL_0, DMA_INTERRUPT_TE)) && (std_dma_get_flag(DMA_FLAG_TE0)))
    {
        std_dma_interrupt_disable(DMA_CHANNEL_0, DMA_INTERRUPT_TE);
        /* 清除DMA通道0传输错误标志位 */
        std_dma_clear_flag(DMA_CLEAR_TE0);
        
        /* 根据应用需求，添加错误处理代码 */
        while(1)
        {
        }
    }
}

/**
* @brief  DMA通道1中断服务函数
* @retval 无
*/
void DMA_Channel1_IRQHandler(void)
{
    /* DMA传输完成中断服务 */
    if((std_dma_get_interrupt_enable(DMA_CHANNEL_1, DMA_INTERRUPT_TF)) && (std_dma_get_flag(DMA_FLAG_TF1)))
    {
        std_dma_interrupt_disable(DMA_CHANNEL_1, DMA_INTERRUPT_TF);
        
        /* 清除DMA通道1所有标志位 */
        std_dma_clear_flag(DMA_CLEAR_G1);
        
        /* 根据应用需求，添加不同应用程序代码 */
        g_ch1_complete = 1;
    }
    
    /* DMA传输错误中断服务 */
    if((std_dma_get_interrupt_enable(DMA_CHANNEL_1, DMA_INTERRUPT_TE)) && (std_dma_get_flag(DMA_FLAG_TE1)))
    {
        std_dma_interrupt_disable(DMA_CHANNEL_1, DMA_INTERRUPT_TE);
        /* 清除DMA通道1传输错误标志位 */
        std_dma_clear_flag(DMA_CLEAR_TE1);
        
        /* 根据应用需求，添加错误处理代码 */
        while(1)
        {
        }
    }
}

/**
* @brief  I2C1 DMA方式发送数据流程
* @retval 无
*/
void bsp_i2c1_slave_send_dma(void)
{
    /* 等待地址匹配 */
    while(!std_i2c_get_flag(I2C1, I2C_FLAG_ADDR));
    /* 清除地址匹配中断标志位 */
    std_i2c_clear_flag(I2C1, I2C_CLEAR_ADDR);
    
    /* 等待DMA传输完成 */
    while(g_ch1_complete == 0);
    
    /* 清除NACKF标志 */
    while(!std_i2c_get_flag(I2C1, I2C_FLAG_NACK));
    std_i2c_clear_flag(I2C1, I2C_CLEAR_NACK);
    
    /* 清除STOPF */
    while(!std_i2c_get_flag(I2C1, I2C_FLAG_STOP));
    std_i2c_clear_flag(I2C1, I2C_FLAG_STOP);
}

/**
* @brief  I2C1 DMA方式接收数据流程
* @retval 无
*/
void bsp_i2c1_slave_receive_dma(void)
{
    /* 等待地址匹配 */
    while(!std_i2c_get_flag(I2C1, I2C_FLAG_ADDR));
    /* 清除地址匹配中断标志位 */
    std_i2c_clear_flag(I2C1, I2C_CLEAR_ADDR);
    
    /* 等待DMA传输完成 */
    while(g_ch0_complete == 0);
    
    /* 清除STOPF */
    while(!std_i2c_get_flag(I2C1, I2C_FLAG_STOP));
    std_i2c_clear_flag(I2C1, I2C_FLAG_STOP);
}

/**
* @brief  I2C DMA Tx通道配置
* @retval 无
*/
void bsp_i2c1_dma_tx_config(void)
{
    std_dma_config_t i2c_dma_config = {0};
    
    i2c_dma_config.dma_channel = DMA_CHANNEL_1;
    i2c_dma_config.src_addr = (uint32_t)g_tx_buffer;
    i2c_dma_config.dst_addr = (uint32_t)&(I2C1->TDR);
    i2c_dma_config.data_number = DATA_LENGTH;
    std_dma_start_transmit(&i2c_dma_config);
}

/**
* @brief  I2C DMA Rx通道配置
* @retval 无
*/
void bsp_i2c1_dma_rx_config(void)
{
    std_dma_config_t i2c_dma_config = {0};
    
    i2c_dma_config.dma_channel = DMA_CHANNEL_0;
    i2c_dma_config.src_addr = (uint32_t)&(I2C1->RDR);
    i2c_dma_config.dst_addr = (uint32_t)g_rx_buffer;
    i2c_dma_config.data_number = DATA_LENGTH;
    std_dma_start_transmit(&i2c_dma_config);
}



