/*******************************************************************************
* File Name : battery.c
* Author :
* Version : V0.0
* Date :
* Description : Battery interface via I2C1
*******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "includes.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define I2C_CK_FREQ 100000
#define I2C_TIMEOUT 0x2000
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/*******************************************************************************
* Function Name : I2C_Init
* Description : Initialize I2C interface.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void I2C_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//I2C_Resume();
/* I2C1 configuration ------------------------------------------------------*/
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0; //DS2786_ADDRESS7;???????
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = I2C_CK_FREQ;
I2C_Cmd(I2C1, ENABLE);
I2C_Init(I2C1, &I2C_InitStructure);
/* Configure and enable I2C1 interrupt
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = I2C1_EV_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
I2C_ITConfig(I2C1, I2C_IT_EVT | I2C_IT_BUF, ENABLE); // Enable I2C1 interrupt
-------------------------------------*/
}
/*******************************************************************************
* Function Name : I2C_ByteWrite
* Description : Writes one byte to the I2C interface.
* Input : - pBuffer : pointer to the buffer containing the data to be
* written to the interface.
* - WriteAddr : interface's internal address to write to.
* Output : None
* Return : None
*******************************************************************************/
bool I2C_ByteWrite(u8 deviceAddr, u8* pBuffer, u8 WriteAddr)
{
bool res=TRUE;
u32 Flag1, Flag2;
int to;
I2C_Resume();
/* Send STRAT condition */
I2C_GenerateSTART(I2C1, ENABLE);
/* Test on EV5 and clear it */
// The following procedure will not wrok because hardware will raise other flag
// so it can't pass the check
//while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
to = I2C_TIMEOUT;
do
{ // This is the workaround procedure to fix hardware bug.
Flag1 = I2C1->SR1;
Flag2 = I2C1->SR2;
if ( !(--to) )
{
//res = FALSE;
//break;
return FALSE;
}
} while(((Flag1|(Flag2<<16)) & 0x00FFFFBF) != I2C_EVENT_MASTER_MODE_SELECT);
/* Send interface address for write */
I2C_Send7bitAddress(I2C1, deviceAddr, I2C_Direction_Transmitter);
/* Test on EV6 and clear it */
to = I2C_TIMEOUT;
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
{
if ( !(--to) )
{
//res = FALSE;
//break;
return FALSE;
}
}
/* Send the interface's internal address to write to */
I2C_SendData(I2C1, WriteAddr);
/* Test on EV8 and clear it */
to = I2C_TIMEOUT;
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
{
if ( !(--to) )
{
//res = FALSE;
//break;
return FALSE;
}
}
/* Send the byte to be written */
I2C_SendData(I2C1, *pBuffer);
/* Test on EV8 and clear it */
to = I2C_TIMEOUT;
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
{
if ( !(--to) )
{
//res = FALSE;
//break;
return FALSE;
}
}
/* Send STOP condition */
I2C_GenerateSTOP(I2C1, ENABLE);
// something wrong in accessing I2C. Reset the peripheral
// if (!res)
// BAT_Configuration();
return res;
}
/*******************************************************************************
* Function Name : I2C_MultiWrite
* Description : Writes more than one byte to the interface with a single WRITE
* cycle. The number of byte can't exceed the interface page size.
* Input : - pBuffer : pointer to the buffer containing the data to be
* written to the interface.
* - WriteAddr : interface's internal address to write to.
* - NumByteToWrite : number of bytes to write to the interface.
* Output : None
* Return : None
*******************************************************************************/
bool I2C_MultiWrite(u8 deviceAddr, u8* pBuffer, u8 WriteAddr, u8 NumByteToWrite)
{
bool res=TRUE;
int to;
I2C_Resume();
/* Send START condition */
I2C_GenerateSTART(I2C1, ENABLE);
/* Test on EV5 and clear it */
to = I2C_TIMEOUT;
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
{
if ( !(--to) )
{
//res = FALSE;
//break;
return FALSE;
}
}
/* Send interface address for write */
I2C_Send7bitAddress(I2C1, deviceAddr, I2C_Direction_Transmitter);
/* Test on EV6 and clear it */
to = I2C_TIMEOUT;
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
{
if ( !(--to) )
{
//res = FALSE;
//break;
return FALSE;
}
}
/* Send the interface's internal address to write to */
I2C_SendData(I2C1, WriteAddr);
/* Test on EV8 and clear it */
to = I2C_TIMEOUT;
while(! I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
{
if ( !(--to) )
{
//res = FALSE;
//break;
return FALSE;
}
}
/* While there is data to be written */
while(NumByteToWrite--)
{
/* Send the current byte */
I2C_SendData(I2C1, *pBuffer);
/* Point to the next byte to be written */
pBuffer++;
/* Test on EV8 and clear it */
to = I2C_TIMEOUT;
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
{
if ( !(--to) )
{
//res = FALSE;
//break;
return FALSE;
}
}
}
/* Send STOP condition */
I2C_GenerateSTOP(I2C1, ENABLE);
// something wrong in accessing I2C. Reset the peripheral
// if (!res)
// BAT_Configuration();
return res;
}
/*******************************************************************************
* Function Name : I2C_BufferRead
* Description : Reads a block of data from the interface.
* Input : - pBuffer : pointer to the buffer that receives the data read
* from the interface.
* - ReadAddr : interface's internal address to read from.
* - NumByteToRead : number of bytes to read from the interface.