1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/notrynohigh-BabyOS

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Это зеркальный репозиторий, синхронизируется ежедневно с исходного репозитория.
Клонировать/Скачать
b_hal_i2c.c 13 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
陈海萌 Отправлено 7 месяцев назад ed3ed74
/**
*!
* \file b_hal_i2c.c
* \version v0.0.1
* \date 2020/03/25
* \author Bean(notrynohigh@outlook.com)
*******************************************************************************
* @attention
*
* Copyright (c) 2020 Bean
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SUARTL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*******************************************************************************
*/
/*Includes ----------------------------------------------*/
#include "hal/inc/b_hal.h"
/**
* \addtogroup B_HAL
* \{
*/
/**
* \addtogroup I2C
* \{
*/
/**
* \defgroup I2C_Private_TypesDefinitions
*/
typedef struct
{
bHalGPIOInstance_t clk;
bHalGPIOInstance_t sda;
uint32_t frq;
} bHalI2CIO_t;
/**
* \}
*/
/**
* \addtogroup I2C_Private_Functions
* \{
*/
// 计算I2C延时微秒数值的函数
static uint32_t _HalCalculateI2CDelayUs(uint32_t i2cFrequency)
{
if (i2cFrequency <= 100000)
{
// Standard Mode (100kHz)
return 5;
}
else if (i2cFrequency <= 200000)
{
return 2;
}
else if (i2cFrequency <= 400000)
{
// Fast Mode (400kHz)
return 1;
}
else if (i2cFrequency <= 1000000)
{
// Fast Mode Plus (1MHz)
return 1;
}
else
{
return 1;
}
}
static void _HalI2CIOStart(bHalI2CIO_t i2c)
{
uint32_t us = _HalCalculateI2CDelayUs(i2c.frq);
bHalGpioWritePin(i2c.sda.port, i2c.sda.pin, 1);
bHalGpioWritePin(i2c.clk.port, i2c.clk.pin, 1);
bHalDelayUs(us);
bHalGpioWritePin(i2c.sda.port, i2c.sda.pin, 0);
bHalDelayUs(us);
bHalGpioWritePin(i2c.clk.port, i2c.clk.pin, 0);
bHalDelayUs(us);
}
static void _HalI2CIOStop(bHalI2CIO_t i2c)
{
uint32_t us = _HalCalculateI2CDelayUs(i2c.frq);
bHalGpioWritePin(i2c.clk.port, i2c.clk.pin, 0);
bHalDelayUs(us);
bHalGpioWritePin(i2c.sda.port, i2c.sda.pin, 0);
bHalDelayUs(us);
bHalGpioWritePin(i2c.clk.port, i2c.clk.pin, 1);
bHalDelayUs(us);
bHalGpioWritePin(i2c.sda.port, i2c.sda.pin, 1);
bHalDelayUs(us);
}
static int _HalI2CIOACK(bHalI2CIO_t i2c)
{
int retval = -1;
uint32_t us = _HalCalculateI2CDelayUs(i2c.frq);
bHalGpioWritePin(i2c.sda.port, i2c.sda.pin, 1);
bHalGpioConfig(i2c.sda.port, i2c.sda.pin, B_HAL_GPIO_INPUT, B_HAL_GPIO_NOPULL);
bHalDelayUs(us);
bHalGpioWritePin(i2c.clk.port, i2c.clk.pin, 1);
bHalDelayUs(us);
if (bHalGpioReadPin(i2c.sda.port, i2c.sda.pin))
{
retval = -1;
}
else
{
retval = 0;
}
bHalGpioWritePin(i2c.clk.port, i2c.clk.pin, 0);
bHalGpioConfig(i2c.sda.port, i2c.sda.pin, B_HAL_GPIO_OUTPUT, B_HAL_GPIO_NOPULL);
bHalDelayUs(us);
return retval;
}
static void _HalI2CIOmACK(bHalI2CIO_t i2c)
{
uint32_t us = _HalCalculateI2CDelayUs(i2c.frq);
bHalGpioWritePin(i2c.sda.port, i2c.sda.pin, 0);
bHalDelayUs(us);
bHalGpioWritePin(i2c.clk.port, i2c.clk.pin, 1);
bHalDelayUs(us);
bHalGpioWritePin(i2c.clk.port, i2c.clk.pin, 0);
bHalDelayUs(us);
bHalGpioWritePin(i2c.sda.port, i2c.sda.pin, 1);
}
static void _HalI2CIOmNACK(bHalI2CIO_t i2c)
{
uint32_t us = _HalCalculateI2CDelayUs(i2c.frq);
bHalGpioWritePin(i2c.sda.port, i2c.sda.pin, 1);
bHalDelayUs(us);
bHalGpioWritePin(i2c.clk.port, i2c.clk.pin, 1);
bHalDelayUs(us);
bHalGpioWritePin(i2c.clk.port, i2c.clk.pin, 0);
bHalDelayUs(us);
}
static void _HalI2CIOWriteByte(bHalI2CIO_t i2c, uint8_t dat)
{
uint8_t i = 0;
uint32_t us = _HalCalculateI2CDelayUs(i2c.frq);
for (i = 0; i < 8; i++)
{
if (dat & 0x80)
{
bHalGpioWritePin(i2c.sda.port, i2c.sda.pin, 1);
}
else
{
bHalGpioWritePin(i2c.sda.port, i2c.sda.pin, 0);
}
bHalGpioWritePin(i2c.clk.port, i2c.clk.pin, 1);
bHalDelayUs(us);
bHalGpioWritePin(i2c.clk.port, i2c.clk.pin, 0);
if (i == 7)
{
bHalGpioWritePin(i2c.sda.port, i2c.sda.pin, 1);
}
dat <<= 1;
bHalDelayUs(us);
}
}
static uint8_t _HalI2CIOReadByte(bHalI2CIO_t i2c, uint8_t mack)
{
uint8_t i = 0, tmp = 0;
uint32_t us = _HalCalculateI2CDelayUs(i2c.frq);
bHalGpioConfig(i2c.sda.port, i2c.sda.pin, B_HAL_GPIO_INPUT, B_HAL_GPIO_NOPULL);
bHalDelayUs(us);
for (i = 0; i < 8; i++)
{
tmp <<= 1;
bHalGpioWritePin(i2c.clk.port, i2c.clk.pin, 1);
bHalDelayUs(us);
if (bHalGpioReadPin(i2c.sda.port, i2c.sda.pin))
{
tmp++;
}
bHalGpioWritePin(i2c.clk.port, i2c.clk.pin, 0);
bHalDelayUs(us);
}
bHalGpioConfig(i2c.sda.port, i2c.sda.pin, B_HAL_GPIO_OUTPUT, B_HAL_GPIO_NOPULL);
bHalDelayUs(us);
if (mack == 0)
_HalI2CIOmNACK(i2c);
else
_HalI2CIOmACK(i2c);
return tmp;
}
static int _HalI2CIOWriteData(bHalI2CIO_t i2c, uint8_t dev, uint8_t *pdat, uint16_t len)
{
uint16_t i;
_HalI2CIOStart(i2c);
_HalI2CIOWriteByte(i2c, dev);
if (_HalI2CIOACK(i2c) < 0)
{
_HalI2CIOStop(i2c);
return -1;
}
for (i = 0; i < len; i++)
{
_HalI2CIOWriteByte(i2c, pdat[i]);
if (_HalI2CIOACK(i2c) < 0)
{
_HalI2CIOStop(i2c);
return -1;
}
}
_HalI2CIOStop(i2c);
return 0;
}
static int _HalI2CIOReadData(bHalI2CIO_t i2c, uint8_t dev, uint8_t *pdat, uint16_t len)
{
uint16_t i;
_HalI2CIOStart(i2c);
_HalI2CIOWriteByte(i2c, dev | 0x1);
if (_HalI2CIOACK(i2c) < 0)
{
_HalI2CIOStop(i2c);
return -1;
}
for (i = 0; i < (len - 1); i++)
{
*pdat = _HalI2CIOReadByte(i2c, 1);
pdat++;
}
*pdat = _HalI2CIOReadByte(i2c, 0);
_HalI2CIOStop(i2c);
return 0;
}
static int _HalI2CIOReadBuff(bHalI2CIO_t i2c, uint8_t dev, uint16_t addr, uint8_t addr_size,
uint8_t *pdat, uint16_t len)
{
_HalI2CIOStart(i2c);
_HalI2CIOWriteByte(i2c, dev);
if (_HalI2CIOACK(i2c) < 0)
{
_HalI2CIOStop(i2c);
return -1;
}
if (addr_size > 1)
{
_HalI2CIOWriteByte(i2c, (uint8_t)((addr & 0xff00) >> 8));
if (_HalI2CIOACK(i2c) < 0)
{
_HalI2CIOStop(i2c);
return -1;
}
}
_HalI2CIOWriteByte(i2c, (uint8_t)(addr & 0x00ff));
if (_HalI2CIOACK(i2c) < 0)
{
_HalI2CIOStop(i2c);
return -1;
}
_HalI2CIOStart(i2c);
_HalI2CIOWriteByte(i2c, dev | 0x1);
if (_HalI2CIOACK(i2c) < 0)
{
_HalI2CIOStop(i2c);
return -1;
}
while (len-- > 1)
{
*pdat++ = _HalI2CIOReadByte(i2c, 1);
}
*pdat++ = _HalI2CIOReadByte(i2c, 0);
_HalI2CIOStop(i2c);
return 0;
}
static int _HalI2CIOWriteBuff(bHalI2CIO_t i2c, uint8_t dev, uint16_t addr, uint8_t addr_size,
const uint8_t *pdat, uint8_t len)
{
uint32_t i = 0;
_HalI2CIOStart(i2c);
_HalI2CIOWriteByte(i2c, dev);
if (_HalI2CIOACK(i2c) < 0)
{
_HalI2CIOStop(i2c);
return -1;
}
if (addr_size > 1)
{
_HalI2CIOWriteByte(i2c, (uint8_t)((addr & 0xff00) >> 8));
if (_HalI2CIOACK(i2c) < 0)
{
_HalI2CIOStop(i2c);
return -1;
}
}
_HalI2CIOWriteByte(i2c, (uint8_t)(addr & 0x00ff));
if (_HalI2CIOACK(i2c) < 0)
{
_HalI2CIOStop(i2c);
return -1;
}
for (i = 0; i < len; i++)
{
_HalI2CIOWriteByte(i2c, pdat[i]);
if (_HalI2CIOACK(i2c) < 0)
{
_HalI2CIOStop(i2c);
return -1;
}
}
_HalI2CIOStop(i2c);
return 0;
}
/**
* \}
*/
/**
* \addtogroup I2C_Exported_Functions
* \{
*/
#if defined(__WEAKDEF)
__WEAKDEF int bMcuI2CReadByte(const bHalI2CIf_t *i2c_if, uint8_t *pbuf, uint16_t len)
{
return -1;
}
__WEAKDEF int bMcuI2CWriteByte(const bHalI2CIf_t *i2c_if, uint8_t *pbuf, uint16_t len)
{
return -1;
}
__WEAKDEF int bMcuI2CMemWrite(const bHalI2CIf_t *i2c_if, uint16_t mem_addr, uint8_t mem_addr_size,
const uint8_t *pbuf, uint16_t len)
{
return -1;
}
__WEAKDEF int bMcuI2CMemRead(const bHalI2CIf_t *i2c_if, uint16_t mem_addr, uint8_t mem_addr_size,
uint8_t *pbuf, uint16_t len)
{
return -1;
}
#endif
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
int bHalI2CReadByte(const bHalI2CIf_t *i2c_if, uint8_t *pbuf, uint16_t len)
{
int retval = 0;
bHalI2CIO_t simulating_iic;
if (IS_NULL(i2c_if) || (IS_NULL(pbuf) && (len > 0)))
{
return -1;
}
if (i2c_if->is_simulation == 1)
{
simulating_iic.clk = i2c_if->_if.simulating_i2c.clk;
simulating_iic.sda = i2c_if->_if.simulating_i2c.sda;
simulating_iic.frq = i2c_if->_if.simulating_i2c.frq;
retval = _HalI2CIOReadData(simulating_iic, i2c_if->dev_addr, pbuf, len);
}
else
{
retval = bMcuI2CReadByte(i2c_if, pbuf, len);
}
return retval;
}
int bHalI2CWriteByte(const bHalI2CIf_t *i2c_if, uint8_t *pbuf, uint16_t len)
{
int retval = 0;
bHalI2CIO_t simulating_iic;
if (IS_NULL(i2c_if) || (IS_NULL(pbuf) && (len > 0)))
{
return -1;
}
if (i2c_if->is_simulation == 1)
{
simulating_iic.clk = i2c_if->_if.simulating_i2c.clk;
simulating_iic.sda = i2c_if->_if.simulating_i2c.sda;
simulating_iic.frq = i2c_if->_if.simulating_i2c.frq;
retval = _HalI2CIOWriteData(simulating_iic, i2c_if->dev_addr, pbuf, len);
}
else
{
retval = bMcuI2CWriteByte(i2c_if, pbuf, len);
}
return retval;
}
int bHalI2CMemWrite(const bHalI2CIf_t *i2c_if, uint16_t mem_addr, uint8_t mem_addr_size,
const uint8_t *pbuf, uint16_t len)
{
int retval = 0;
bHalI2CIO_t simulating_iic;
if (IS_NULL(i2c_if) || (IS_NULL(pbuf) && (len > 0)))
{
return -1;
}
if (i2c_if->is_simulation == 1)
{
simulating_iic.clk = i2c_if->_if.simulating_i2c.clk;
simulating_iic.sda = i2c_if->_if.simulating_i2c.sda;
simulating_iic.frq = i2c_if->_if.simulating_i2c.frq;
retval = _HalI2CIOWriteBuff(simulating_iic, i2c_if->dev_addr, mem_addr, mem_addr_size, pbuf,
len);
}
else
{
retval = bMcuI2CMemWrite(i2c_if, mem_addr, mem_addr_size, pbuf, len);
}
return retval;
}
int bHalI2CMemRead(const bHalI2CIf_t *i2c_if, uint16_t mem_addr, uint8_t mem_addr_size,
uint8_t *pbuf, uint16_t len)
{
int retval = 0;
bHalI2CIO_t simulating_iic;
if (IS_NULL(i2c_if) || (IS_NULL(pbuf) && (len > 0)))
{
return -1;
}
if (i2c_if->is_simulation == 1)
{
simulating_iic.clk = i2c_if->_if.simulating_i2c.clk;
simulating_iic.sda = i2c_if->_if.simulating_i2c.sda;
simulating_iic.frq = i2c_if->_if.simulating_i2c.frq;
retval =
_HalI2CIOReadBuff(simulating_iic, i2c_if->dev_addr, mem_addr, mem_addr_size, pbuf, len);
}
else
{
retval = bMcuI2CMemRead(i2c_if, mem_addr, mem_addr_size, pbuf, len);
}
return retval;
}
int bHalI2CAddressCheck(const bHalI2CIf_t *i2c_if)
{
int retval = 0;
uint8_t dummy = i2c_if->dev_addr;
bHalI2CIO_t simulating_iic;
if (IS_NULL(i2c_if))
{
return -1;
}
if (i2c_if->is_simulation == 1)
{
simulating_iic.clk = i2c_if->_if.simulating_i2c.clk;
simulating_iic.sda = i2c_if->_if.simulating_i2c.sda;
simulating_iic.frq = i2c_if->_if.simulating_i2c.frq;
retval = _HalI2CIOWriteData(simulating_iic, i2c_if->dev_addr, &dummy, 0);
}
else
{
retval = bMcuI2CWriteByte(i2c_if, &dummy, 0);
}
return retval;
}
/**
* \}
*/
/**
* \}
*/
/**
* \}
*/
/************************ Copyright (c) 2019 Bean *****END OF FILE****/

Комментарий ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://gitlife.ru/oschina-mirror/notrynohigh-BabyOS.git
git@gitlife.ru:oschina-mirror/notrynohigh-BabyOS.git
oschina-mirror
notrynohigh-BabyOS
notrynohigh-BabyOS
master