
/* Copyright Statement:
 *
 * This software/firmware and related documentation ("AutoChips Software") are
 * protected under relevant copyright laws. The information contained herein is
 * confidential and proprietary to AutoChips Inc. and/or its licensors. Without
 * the prior written permission of AutoChips inc. and/or its licensors,  any
 * reproduction,  modification,  use or disclosure of AutoChips Software,  and
 * information contained herein,  in whole or in part,  shall be strictly
 * prohibited.
 *
 * AutoChips Inc. (C) 2023. All rights reserved.
 *
 * BY OPENING THIS FILE,  RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
 * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("AUTOCHIPS SOFTWARE")
 * RECEIVED FROM AUTOCHIPS AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
 * ON AN "AS-IS" BASIS ONLY. AUTOCHIPS EXPRESSLY DISCLAIMS ANY AND ALL
 * WARRANTIES,  EXPRESS OR IMPLIED,  INCLUDING BUT NOT LIMITED TO THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE OR
 * NONINFRINGEMENT. NEITHER DOES AUTOCHIPS PROVIDE ANY WARRANTY WHATSOEVER WITH
 * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
 * INCORPORATED IN,  OR SUPPLIED WITH THE AUTOCHIPS SOFTWARE,  AND RECEIVER AGREES
 * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
 * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
 * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN AUTOCHIPS
 * SOFTWARE. AUTOCHIPS SHALL ALSO NOT BE RESPONSIBLE FOR ANY AUTOCHIPS SOFTWARE
 * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
 * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND AUTOCHIPS'S
 * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE AUTOCHIPS SOFTWARE
 * RELEASED HEREUNDER WILL BE,  AT AUTOCHIPS'S OPTION,  TO REVISE OR REPLACE THE
 * AUTOCHIPS SOFTWARE AT ISSUE,  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
 * CHARGE PAID BY RECEIVER TO AUTOCHIPS FOR SUCH AUTOCHIPS SOFTWARE AT ISSUE.
 */

/*************<start>******************/


/*************<include>****************/
#include "string.h"
#include "gpio.h"
#include "i2c.h"

/*************<macro>******************/
#define I2C_CMD_BUF_LEN     (4)
#define I2C_TST_BUF_LEN     (1024)

/*************<enum>*******************/


/*************<union>******************/


/*************<struct>*****************/


/*************<variable>***************/
uint8_t     g_tstDataBuf[I2C_TST_BUF_LEN];
uint8_t     g_slvDataRdyCur;

/*************<prototype>**************/
void EXTI9_15_Callback(void *device, uint32_t wpara, uint32_t lpara);

/**
* @prototype I2C_ParaInit(void)
*
* @param[in] void
* @return    void
*
* @brief     Init I2C.
*/
void I2C_ParaInit(void)
{
    I2C_ConfigType i2cConfig;

    /*Initialize pin function to I2C.*/
    GPIO_SetFunc(I2C0_SCL_PORT, I2C0_SCL_PIN, GPIO_FUN3);
    GPIO_SetFunc(I2C0_SDA_PORT, I2C0_SDA_PIN, GPIO_FUN3);

    GPIO_SetFunc(I2C_SLV_RDY_PORT, I2C_SLV_RDY_PIN, GPIO_FUN0);
    GPIO_SetDir(I2C_SLV_RDY_PORT, I2C_SLV_RDY_PIN, GPIO_IN);
    GPIO_SetPulldown(I2C_SLV_RDY_PORT, I2C_SLV_RDY_PIN, ENABLE);
    GPIO_EnableExtInterrupt(I2C_SLV_RDY_PORT, I2C_SLV_RDY_PIN, EXTI_TRIGGER_RISING_FALLING);
    GPIO_SetCallback(I2C_SLV_RDY_PIN, EXTI9_15_Callback);

    /*Zeroing structural variables.*/
    memset(&i2cConfig, 0x00, sizeof(i2cConfig));

    /*Parameters that need to be configured for both host and slave modes.*/
    i2cConfig.mode              = I2C_MASTER;/*Set Master Slave Mode.*/
    i2cConfig.extAddrEn         = DISABLE;   /*10bit extended address disable.*/
    i2cConfig.dmaRxEn           = DISABLE;   /*Set DMA reception data.*/
    i2cConfig.dmaTxEn           = DISABLE;   /*Set DMA to send data.*/
    i2cConfig.interruptEn       = DISABLE;   /*I2C interrupt,BND/SAMF/ARBLOST.*/
    i2cConfig.nackInterruptEn   = DISABLE;   /*NACK interrupt.*/
    i2cConfig.ssInterruptEn     = DISABLE;   /*bus start or stop interrupt.*/
    i2cConfig.i2cEn             = ENABLE;    /*Enabling module.*/
    i2cConfig.callBack          = NULL;      /*Interrupt callback function.*/

    /*The parameters that need to be configured in the host mode can be ignored when configured in the slave mode.*/
    i2cConfig.masterConfig.sampleCnt = 9;/*Set the baud rate to 100Kbps, bandrate=(32M/(10 * 16 * 2))=100Kbps.*/
    i2cConfig.masterConfig.stepCnt   = 15;
    i2cConfig.masterConfig.ARBEn     = ENABLE;/*Set host arbitration function.*/
    i2cConfig.masterConfig.SYNCEn    = ENABLE;/*Set host SCL synchronization function.*/

    /*The parameters that need to be configured in slave mode can be ignored when configured in master mode.*/
    i2cConfig.slaveConfig.slaveAddr      = I2C_SLV_ADDR;/*Slave address.*/
    i2cConfig.slaveConfig.slaveRangeAddr = 0;           /*Slave range address.*/
    i2cConfig.slaveConfig.glitchFilterCnt = 0;          /*Burr filtration.*/
    i2cConfig.slaveConfig.stretchEn      = DISABLE;     /*Slave SCL extension function.*/
    i2cConfig.slaveConfig.rangeAddrEn    = DISABLE;     /*Prohibited range address.*/
    i2cConfig.slaveConfig.monitorEn      = DISABLE;     /*Disable slave monitoring function.*/
    i2cConfig.slaveConfig.generalCallEn  = DISABLE;     /*Disable slave monitoring function.*/
    i2cConfig.slaveConfig.wakeupEn       = DISABLE;     /*Wake up function, only effective during slave mode.*/
    i2cConfig.slaveConfig.rxOFInterruptEn   = DISABLE;  /*Receive cache overflow interrupt.*/
    i2cConfig.slaveConfig.txUFInterruptEn   = DISABLE;  /*Send cache overflow interrupt.*/

    I2C_Init(I2C0, &i2cConfig);
}

/**
* @prototype I2C_Transmit1KBytes(void)
*
* @param[in] void
* @return    void
*
* @brief     Send 1024 bytes of dat.
*/
void I2C_Transmit1KBytes(void)
{
    uint8_t tempCmdBuf[4] = {0xAC, 0x78, 0x01, 0x53};

    /*Prepare data.*/
    for (uint16_t ii = 0; ii < I2C_TST_BUF_LEN; ii++)
    {
        g_tstDataBuf[ii] = ii;
        printf("%d ", g_tstDataBuf[ii]);
    }
    printf("\r\n");

    /*Sending instructions.*/
    while (!g_slvDataRdyCur); /*Waiting for the slave to be ready to receive instructions*/
    g_slvDataRdyCur = FALSE;
    I2C_MasterTransmitPoll(I2C0, I2C_SLV_ADDR, tempCmdBuf, I2C_CMD_BUF_LEN, DISABLE);

    /*send data.*/
    while (!g_slvDataRdyCur); /*Waiting for the slave to be ready to receive data*/
    g_slvDataRdyCur = FALSE;
    I2C_MasterTransmitPoll(I2C0, I2C_SLV_ADDR, g_tstDataBuf, I2C_TST_BUF_LEN, ENABLE);
}

/**
* @prototype I2C_Receive1KBytes(void)
*
* @param[in] void
* @return    void
*
* @brief     Receive 1024 bytes of data.
*/
void I2C_Receive1KBytes(void)
{
    uint8_t tempCmdBuf[4] = {0xAC, 0x78, 0x01, 0x52};

    /*Clear buffer.*/
    memset(g_tstDataBuf, 0x00, I2C_TST_BUF_LEN);

    /*Sending instructions.*/
    while (!g_slvDataRdyCur); /*Waiting for the slave to be ready to receive instructions*/
    g_slvDataRdyCur = FALSE;
    I2C_MasterTransmitPoll(I2C0, I2C_SLV_ADDR, tempCmdBuf, I2C_CMD_BUF_LEN, DISABLE);

    /*Receive Data.*/
    while (!g_slvDataRdyCur); /*Waiting for the slave to be ready to receive data*/
    g_slvDataRdyCur = FALSE;
    I2C_MasterReceivePoll(I2C0, I2C_SLV_ADDR, g_tstDataBuf, I2C_TST_BUF_LEN);

    /*print data.*/
    for (uint16_t ii = 0; ii < I2C_TST_BUF_LEN; ii++)
    {
        printf("%d ", g_tstDataBuf[ii]);
    }
    printf("\r\n");
}

/**
* @prototype EXTI9_15_Callback(void *device, uint32_t wpara, uint32_t lpara)
*
* @param[in] ...
* @return    void
*
* @brief     External interrupt callback function.
*/
void EXTI9_15_Callback(void *device, uint32_t wpara, uint32_t lpara)
{
    if ((device == I2C_SLV_RDY_PORT) && (wpara == I2C_SLV_RDY_PIN))
    {
        g_slvDataRdyCur = TRUE;
    }
}


/*************<end>********************/
