mirror of
https://gitee.com/Lyon1998/pikapython.git
synced 2025-01-22 17:12:55 +08:00
216 lines
3.4 KiB
C
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;
|
||
|
}
|