ChipTest/PAN159/PAN159-Template/Library/StdDriver/driver/lib_driver_iic_pan159.c
2021-09-26 17:19:12 +08:00

217 lines
7.1 KiB
C

/*******************************************************************************
* @note Copyright (C) 2018 Shanghai Panchip Microelectronics Co., Ltd.
* All rights reserved.
*
* @file lib_driver_iic_pan159.c
* @brief PAN159 hardware IICÇý¶¯
*
* @history - V1.0, 2018-01-19, huoweibin, first implementation.
*******************************************************************************/
#include "lib_driver_iic_pan159.h"
//#include <string.h>
uint8_t g_u8DeviceAddr;
uint8_t g_u8RegAddr;
//uint8_t g_au8TxData[64];
//uint8_t g_u8RxData[64];
uint8_t g_u8DataLen;
uint8_t g_u8DataLenMax;
uint8_t __IO g_u8EndFlag = 0;
typedef void (*TCallback)(void);
typedef void (*I2C_FUNC)(uint32_t u32Status,uint8_t *buf,TCallback cbk, TCallback fail_cbk);
I2C_FUNC __IO s_I2CHandlerFn = NULL;
TCallback __IO cbk_success = NULL;
TCallback __IO cbk_failed = NULL;
uint8_t* buf_addr = NULL;
/*---------------------------------------------------------------------------------------------------------*/
/* I2C IRQ Handler */
/*---------------------------------------------------------------------------------------------------------*/
void I2C0_IRQHandler(void)
{
uint32_t u32Status;
u32Status = I2C_GET_STATUS(I2C0);
if (I2C_GET_TIMEOUT_FLAG(I2C0)) {
/* Clear I2C Timeout Flag */
I2C_ClearTimeoutFlag(I2C0);
}
else {
if (s_I2CHandlerFn != NULL)
s_I2CHandlerFn(u32Status,buf_addr,cbk_success,cbk_failed);
}
}
void iic_pan159_init(void)
{
//uint32_t u32Div;
CLK_EnableModuleClock(I2C0_MODULE);
SYS->P3_MFP &= ~SYS_MFP_P34_Msk;
SYS->P3_MFP |= SYS_MFP_P34_I2C0_SDA;
SYS->P3_MFP &= ~SYS_MFP_P35_Msk;
SYS->P3_MFP |= SYS_MFP_P35_I2C0_SCL;
SYS->IPRST1 |= SYS_IPRST1_I2C0RST_Msk;
SYS->IPRST1 &= ~SYS_IPRST1_I2C0RST_Msk;
I2C_Open(I2C0,400000);
// u32Div = (uint32_t) (((SystemCoreClock * 10)/(400000 * 4) + 5) / 10 - 1); /* Compute proper divider for I2C clock */
// I2C0->CLKDIV = u32Div;
// I2C0->CTL |= I2C_CTL_I2CEN_Msk;
I2C0->CTL |= I2C_CTL_INTEN_Msk;
NVIC_EnableIRQ(I2C0_IRQn);
}
void iic_master_tx(uint32_t u32Status ,uint8_t *buf, TCallback cbk, TCallback fail_cbk)
{
if (u32Status == 0x08) { /* START has been transmitted */
I2C_SET_DATA(I2C0, g_u8DeviceAddr << 1); /* Write SLA+W to Register I2CDAT */
I2C_SET_CONTROL_REG(I2C0, I2C_SI);
}
else if (u32Status == 0x18) { /* SLA+W has been transmitted and ACK has been received */
I2C_SET_DATA(I2C0, g_u8RegAddr);
I2C_SET_CONTROL_REG(I2C0, I2C_SI);
}
else if (u32Status == 0x20) { /* SLA+W has been transmitted and NACK has been received */
I2C_SET_CONTROL_REG(I2C0, I2C_STO | I2C_SI);
}
else if (u32Status == 0x28) { /* DATA has been transmitted and ACK has been received */
if (g_u8DataLen != g_u8DataLenMax) {
I2C_SET_DATA(I2C0, buf[g_u8DataLen++]);
I2C_SET_CONTROL_REG(I2C0, I2C_SI);
} else {
I2C_SET_CONTROL_REG(I2C0, I2C_STO | I2C_SI);
g_u8EndFlag = 1;
if(cbk != NULL)
{
cbk();
}
}
}
else {
if(fail_cbk != NULL)
{
fail_cbk();
}
//I2C_STOP(I2C0);
//(I2C0)->CTL |= (I2C_CTL_SI_Msk | I2C_CTL_STO_Msk);
/* TO DO */
// printf("Status 0x%x is NOT processed\n", u32Status);
}
}
void iic_master_rx(uint32_t u32Status ,uint8_t *buf,TCallback cbk, TCallback fail_cbk){
if (u32Status == 0x08) { /* START has been transmitted and prepare SLA+W */
I2C_SET_DATA(I2C0, g_u8DeviceAddr << 1); /* Write SLA+W to Register I2CDAT */
I2C_SET_CONTROL_REG(I2C0, I2C_SI);
}
else if (u32Status == 0x18) { /* SLA+W has been transmitted and ACK has been received */
I2C_SET_DATA(I2C0, g_u8RegAddr);
I2C_SET_CONTROL_REG(I2C0, I2C_SI);
}
else if (u32Status == 0x20) { /* SLA+W has been transmitted and NACK has been received */
I2C_SET_CONTROL_REG(I2C0, I2C_STO | I2C_SI);
}
else if (u32Status == 0x28) { /* DATA has been transmitted and ACK has been received */
I2C_SET_CONTROL_REG(I2C0, I2C_STA | I2C_SI);
}
else if (u32Status == 0x10) { /* Repeat START has been transmitted and prepare SLA+R */
I2C_SET_DATA(I2C0, ((g_u8DeviceAddr << 1) | 0x01)); /* Write SLA+R to Register I2CDAT */
I2C_SET_CONTROL_REG(I2C0, I2C_SI);
}
else if (u32Status == 0x40) { /* SLA+R has been transmitted and ACK has been received */
if(g_u8DataLenMax== 1)
{
I2C_SET_CONTROL_REG(I2C0, I2C_SI );
}
else{
I2C_SET_CONTROL_REG(I2C0, I2C_SI | I2C_AA );
}
}
else if (u32Status == 0x50) { /* DATA has been received and ACK has been returned */
if(g_u8DataLen != g_u8DataLenMax-2){
buf[g_u8DataLen++] = I2C_GET_DATA(I2C0);
I2C_SET_CONTROL_REG(I2C0, I2C_SI | I2C_AA);
}
else{
buf[g_u8DataLen++] = I2C_GET_DATA(I2C0);
I2C_SET_CONTROL_REG(I2C0, I2C_SI );
}
}
else if (u32Status == 0x58) { /* DATA has been received and NACK has been returned */
buf[g_u8DataLen++] = I2C_GET_DATA(I2C0);
I2C_SET_CONTROL_REG(I2C0, I2C_STO | I2C_SI);
g_u8EndFlag = 1;
if(cbk != NULL)
{
cbk();
}
}
else {
if(fail_cbk != NULL)
{
fail_cbk();
}
//(I2C0)->CTL |= (I2C_CTL_SI_Msk | I2C_CTL_STO_Msk);
//I2C_STOP(I2C0);
/* TO DO */
//printf("Status 0x%x is NOT processed\n", u32Status);
}
}
void iic_start_send_bytes(uint16_t devAddr,uint8_t regAddr, uint8_t *buf, uint8_t len,TCallback cbk, TCallback fail_cbk)
{
I2C0->CTL |= I2C_CTL_I2CEN_Msk;
I2C0->CTL |= I2C_CTL_INTEN_Msk;
g_u8DataLenMax = len;
g_u8DeviceAddr = devAddr;
g_u8RegAddr = regAddr;
g_u8DataLen = 0;
g_u8EndFlag = 0;
/* I2C function to write data to slave */
s_I2CHandlerFn = (I2C_FUNC)iic_master_tx;
cbk_success = cbk;
cbk_failed = fail_cbk;
buf_addr = buf;
/* I2C as master sends START signal */
I2C_START(I2C0);
}
void iic_start_read_bytes(uint16_t devAddr,uint8_t regAddr, uint8_t *buf, uint8_t len,TCallback cbk, TCallback fail_cbk)
{
I2C0->CTL |= I2C_CTL_I2CEN_Msk;
I2C0->CTL |= I2C_CTL_INTEN_Msk;
g_u8DataLenMax = len;
g_u8DeviceAddr = devAddr;
g_u8RegAddr = regAddr;
g_u8DataLen = 0;
g_u8EndFlag = 0;
s_I2CHandlerFn = (I2C_FUNC)iic_master_rx;
cbk_success = cbk;
cbk_failed = fail_cbk;
buf_addr = buf;
//CLK_SysTickDelay(5000);
/* I2C as master sends START signal */
I2C_START(I2C0);
//while (g_u8EndFlag == 0);
}
uint8_t is_iic_busy(void)
{
if(g_u8EndFlag){
return 0;
}
else{
return 1;
}
}