2022-02-18 11:27:58 +08:00

216 lines
3.4 KiB
C

#include "wm_i2c.h"
static void delay_us(void)
{
uint32_t i;
for (i = 0; i < (45 * 5); i++)
{
__NOP();
}
}
static void I2C_Start(I2C_HandleTypeDef *hi2c)
{
I2C_SCL_H(hi2c);
I2C_SDA_H(hi2c);
delay_us();
I2C_SDA_L(hi2c);
delay_us();
I2C_SCL_L(hi2c);
delay_us();
}
static void I2C_Stop(I2C_HandleTypeDef *hi2c)
{
I2C_SDA_L(hi2c);
I2C_SCL_H(hi2c);
delay_us();
I2C_SDA_H(hi2c);
delay_us();
}
static void I2C_Ack(I2C_HandleTypeDef *hi2c)
{
I2C_SDA_OUT(hi2c);
I2C_SDA_L(hi2c);
I2C_SCL_H(hi2c);
delay_us();
I2C_SCL_L(hi2c);
delay_us();
I2C_SDA_IN(hi2c);
}
static void I2C_Nack(I2C_HandleTypeDef *hi2c)
{
I2C_SDA_OUT(hi2c);
I2C_SDA_H(hi2c);
I2C_SCL_H(hi2c);
delay_us();
I2C_SCL_L(hi2c);
delay_us();
I2C_SDA_IN(hi2c);
}
static uint8_t I2C_Wait_Ack(I2C_HandleTypeDef *hi2c)
{
uint8_t ack;
I2C_SDA_H(hi2c);
delay_us();
I2C_SDA_IN(hi2c);
I2C_SCL_H(hi2c);
delay_us();
ack = I2C_SDA_GET(hi2c);
I2C_SCL_L(hi2c);
delay_us();
I2C_SDA_OUT(hi2c);
return ack;
}
static void I2C_Write_Byte(I2C_HandleTypeDef *hi2c, uint8_t data)
{
int i;
for (i = 0; i < 8; i ++)
{
if (data & 0x80)
{
I2C_SDA_H(hi2c);
}
else
{
I2C_SDA_L(hi2c);
}
I2C_SCL_H(hi2c);
delay_us();
I2C_SCL_L(hi2c);
delay_us();
data <<= 1;
}
}
static uint8_t I2C_Read_Byte(I2C_HandleTypeDef *hi2c)
{
uint8_t i, temp = 0;
for (i = 0; i < 8; i++)
{
I2C_SCL_H(hi2c);
delay_us();
temp <<= 1;
if (I2C_SDA_GET(hi2c))
{
temp |= 0x01;
}
I2C_SCL_L(hi2c);
delay_us();
}
return temp;
}
HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = hi2c->SCL_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(hi2c->SCL_Port, &GPIO_InitStruct);
GPIO_InitStruct.Pin = hi2c->SDA_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(hi2c->SDA_Port, &GPIO_InitStruct);
HAL_GPIO_WritePin(hi2c->SCL_Port, hi2c->SCL_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(hi2c->SDA_Port, hi2c->SDA_Pin, GPIO_PIN_SET);
return HAL_OK;
}
HAL_StatusTypeDef HAL_I2C_DeInit(I2C_HandleTypeDef *hi2c)
{
HAL_GPIO_DeInit(hi2c->SCL_Port, hi2c->SCL_Pin);
HAL_GPIO_DeInit(hi2c->SDA_Port, hi2c->SDA_Pin);
return HAL_OK;
}
HAL_StatusTypeDef HAL_I2C_Write(I2C_HandleTypeDef *hi2c, uint8_t DevAddress, uint8_t MemAddress, uint8_t *pData, uint16_t Size)
{
uint32_t i, ret = HAL_ERROR;
I2C_Start(hi2c);
I2C_Write_Byte(hi2c, (DevAddress & 0xFE));
if (I2C_Wait_Ack(hi2c))
{
goto OUT;
}
I2C_Write_Byte(hi2c, MemAddress);
if (I2C_Wait_Ack(hi2c))
{
goto OUT;
}
for (i = 0; i < Size; i++)
{
I2C_Write_Byte(hi2c, pData[i]);
if (I2C_Wait_Ack(hi2c))
{
goto OUT;
}
}
ret = HAL_OK;
OUT:
I2C_Stop(hi2c);
return ret;
}
HAL_StatusTypeDef HAL_I2C_Read(I2C_HandleTypeDef *hi2c, uint8_t DevAddress, uint8_t MemAddress, uint8_t *pData, uint16_t Size)
{
uint32_t i, ret = HAL_ERROR;
I2C_Start(hi2c);
I2C_Write_Byte(hi2c, (DevAddress & 0xFE));
if (I2C_Wait_Ack(hi2c))
{
goto OUT;
}
I2C_Write_Byte(hi2c, MemAddress);
if (I2C_Wait_Ack(hi2c))
{
goto OUT;
}
I2C_Start(hi2c);
I2C_Write_Byte(hi2c, (DevAddress | 0x01));
if (I2C_Wait_Ack(hi2c))
{
goto OUT;
}
I2C_SDA_IN(hi2c);
for (i = 0; i < Size; i++)
{
pData[i] = I2C_Read_Byte(hi2c);
if (i == (Size - 1))
{
I2C_Nack(hi2c);
}
else
{
I2C_Ack(hi2c);
}
}
ret = HAL_OK;
OUT:
I2C_SDA_OUT(hi2c);
I2C_Stop(hi2c);
return ret;
}