This commit is contained in:
cfif 2024-12-04 13:10:48 +03:00
commit 383dbbe136
3 changed files with 330 additions and 0 deletions

22
Inc/I2cPortNation.h Normal file
View File

@ -0,0 +1,22 @@
//
// Created by xemon on 13.10.22.
//
#ifndef UVEOS_ON_NATION_I2CPORTNATION_H
#define UVEOS_ON_NATION_I2CPORTNATION_H
#include "I2cIO.h"
#include "SpiPortNation.h"
#include "n32g45x_i2c.h"
typedef struct {
I2C_Module *I2Cx;
I2C_InitType initStruct;
} tI2cPortNation;
void vI2cPortNationInit7bit(tI2cPortNation *env, I2C_Module *I2Cx, uint32_t I2C_Speed);
tI2cIO I2cPortNation_GetIO(tI2cPortNation *env);
#endif //UVEOS_ON_NATION_I2CPORTNATION_H

281
Src/I2cPortNation.c Normal file
View File

@ -0,0 +1,281 @@
//
// Created by xemon on 13.10.22.
//
#include "I2cPortNation.h"
#include "SystemDelayInterface.h"
bool vI2cPortNationWaitBusy(tI2cPortNation *env, uint32_t endTimeout) {
while (I2C_GetFlag(env->I2Cx, I2C_FLAG_BUSY)) {
if (SystemGetMs() > endTimeout)return true;
}
return false;
}
bool vI2cPortNationWaitMasterMode(tI2cPortNation *env, uint32_t endTimeout) {
while (!I2C_CheckEvent(env->I2Cx, I2C_EVT_MASTER_MODE_FLAG)) {
if (SystemGetMs() > endTimeout)return true;
}
return false;
}
bool vI2cPortNationWaitTxAllow(tI2cPortNation *env, uint32_t endTimeout) {
while (!I2C_CheckEvent(env->I2Cx, I2C_EVT_MASTER_TXMODE_FLAG)) {
if (SystemGetMs() > endTimeout)return true;
}
return false;
}
bool vI2cPortNationWaitRxAllow(tI2cPortNation *env, uint32_t endTimeout) {
while (!I2C_CheckEvent(env->I2Cx, I2C_EVT_MASTER_DATA_RECVD_FLAG)) {
if (SystemGetMs() > endTimeout)return true;
}
return false;
}
bool vI2cPortNationWaitByteFull(tI2cPortNation *env, uint32_t endTimeout) {
while (!I2C_GetFlag(env->I2Cx, I2C_FLAG_BYTEF)) {
if (SystemGetMs() > endTimeout)return true;
}
return false;
}
bool vI2cPortNationWaitDataSend(tI2cPortNation *env, uint32_t endTimeout) {
while (!I2C_CheckEvent(env->I2Cx, I2C_EVT_MASTER_DATA_SENDED)) {
if (SystemGetMs() > endTimeout)return true;
}
return false;
}
void vI2cPortNationSendAddr(tI2cPortNation *env, uint16_t devAddress, uint8_t direction) {
if (env->initStruct.AddrMode == I2C_ADDR_MODE_7BIT) {
I2C_SendAddr7bit(env->I2Cx, devAddress, direction);
} else {
assert_param(env->initStruct.AddrMode == I2C_ADDR_MODE_7BIT);
}
}
///?????
bool vI2cPortNationWaitAddrf(tI2cPortNation *env, uint32_t endTimeout) {
while (!I2C_GetFlag(env->I2Cx, I2C_FLAG_ADDRF)) {
if (SystemGetMs() > endTimeout)return true;
}
return false;
}
#define I2C_NATION_RETURN_SEND() return dataByte - data;
//Return if error
#define I2C_NATION_RIFE(FUNC) if(FUNC){ I2C_GenerateStop(env->I2Cx, ENABLE); return dataByte - data;}
uint16_t vI2cPortNationWrite(tI2cPortNation *env, uint16_t devAddress, uint8_t *data, uint16_t size, uint32_t timeout) {
uint32_t endTimeout = SystemGetMs() + timeout;
uint8_t *dataByte = data;
uint8_t *dataEnd = data + size;
I2C_NATION_RIFE(vI2cPortNationWaitBusy(env, endTimeout))
I2C_GenerateStart(env->I2Cx, ENABLE);
if (env->initStruct.AckEnable == I2C_ACKEN) {
I2C_NATION_RIFE(vI2cPortNationWaitMasterMode(env, endTimeout))
}
vI2cPortNationSendAddr(env, devAddress, I2C_DIRECTION_SEND);
I2C_NATION_RIFE(vI2cPortNationWaitTxAllow(env, endTimeout))
while ((SystemGetMs() < endTimeout) && (dataByte < dataEnd)) {
I2C_SendData(env->I2Cx, *dataByte);
I2C_NATION_RIFE(vI2cPortNationWaitDataSend(env, endTimeout))
++dataByte;
}
I2C_GenerateStop(env->I2Cx, ENABLE);
I2C_NATION_RETURN_SEND();
}
#define I2C_NATION_READ_ONE_DATA_BYTE() *dataByte = I2C_RecvData(env->I2Cx); ++dataByte; --left
uint16_t vI2cPortNationRead(tI2cPortNation *env, uint16_t devAddress, uint8_t *data, uint16_t size, uint32_t timeout) {
uint32_t endTimeout = SystemGetMs() + timeout;
uint8_t *dataByte = data;
uint8_t *dataEnd = data + size;
I2C_NATION_RIFE(vI2cPortNationWaitBusy(env, endTimeout))
I2C_GenerateStart(env->I2Cx, ENABLE);
I2C_NATION_RIFE(vI2cPortNationWaitMasterMode(env, endTimeout))
vI2cPortNationSendAddr(env, devAddress, I2C_DIRECTION_RECV);
I2C_NATION_RIFE(vI2cPortNationWaitAddrf(env, endTimeout))
/** While there is data to be read */
if (size == 1) {
/** Disable Acknowledgement */
I2C_ConfigAck(env->I2Cx, DISABLE);
(void) (env->I2Cx->STS1); /// clear ADDR
(void) (env->I2Cx->STS2);
I2C_GenerateStop(env->I2Cx, ENABLE);
} else if (size == 2) {
env->I2Cx->CTRL1 |= 0x0800; /// set POSEN
(void) (env->I2Cx->STS1);
(void) (env->I2Cx->STS2);
I2C_ConfigAck(env->I2Cx, DISABLE);
} else {
I2C_ConfigAck(env->I2Cx, ENABLE);
(void) (env->I2Cx->STS1);
(void) (env->I2Cx->STS2);
}
uint16_t left = size;
while ((SystemGetMs() < endTimeout) && (dataByte < dataEnd)) {
if (size <= 3) {
/** One byte */
if (left == 1) {
I2C_NATION_RIFE(vI2cPortNationWaitRxAllow(env, endTimeout))
I2C_NATION_READ_ONE_DATA_BYTE();
}
/** Two bytes */
else if (left == 2) {
I2C_NATION_RIFE(vI2cPortNationWaitByteFull(env, endTimeout))
I2C_GenerateStop(env->I2Cx, ENABLE);
I2C_NATION_READ_ONE_DATA_BYTE();
I2C_NATION_READ_ONE_DATA_BYTE();
}
/** 3 Last bytes */
else {
I2C_NATION_RIFE(vI2cPortNationWaitByteFull(env, endTimeout))
I2C_ConfigAck(env->I2Cx, DISABLE);
I2C_NATION_READ_ONE_DATA_BYTE();
I2C_NATION_RIFE(vI2cPortNationWaitByteFull(env, endTimeout))
I2C_GenerateStop(env->I2Cx, ENABLE);
I2C_NATION_READ_ONE_DATA_BYTE();
I2C_NATION_READ_ONE_DATA_BYTE();
}
} else {
I2C_NATION_RIFE(vI2cPortNationWaitRxAllow(env, endTimeout))
I2C_NATION_READ_ONE_DATA_BYTE();
if (I2C_GetFlag(env->I2Cx, I2C_FLAG_BYTEF)) {
I2C_NATION_READ_ONE_DATA_BYTE();
}
}
}
I2C_NATION_RETURN_SEND()
}
//void dfad() {
// /** GPIO configuration and clock enable */
// GPIO_InitType GPIO_InitStructure;
//
//
// /** enable peripheral clk*/
// RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_I2C1, ENABLE);
//
// RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOB, ENABLE);
// RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOB, ENABLE);
//
// RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO, ENABLE);
// GPIO_ConfigPinRemap(GPIO_RMP_I2C1, ENABLE);
//
//
// GPIO_InitStructure.Pin = I2Cx_SCL_PIN | I2Cx_SDA_PIN;
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
// GPIO_InitPeripheral(GPIOx, &GPIO_InitStructure);
//
//}
//void initNvic() {
//#if PROCESS_MODE == 1 /* interrupt */
// /** I2C NVIC configuration */
// NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
// NVIC_InitStructure.NVIC_IRQChannel = I2C1_EV_IRQn;
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
// NVIC_Init(&NVIC_InitStructure);
// NVIC_InitStructure.NVIC_IRQChannel = I2C1_ER_IRQn;
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
// NVIC_Init(&NVIC_InitStructure);
//#elif PROCESS_MODE == 2 /* DMA */
// RCC_EnableAHBPeriphClk(RCC_AHBPERIPH_DMA1, ENABLE);
//#endif
//}
void vI2cPortNationInit7bit(tI2cPortNation *env, I2C_Module *I2Cx, uint32_t I2C_Speed) {
I2C_InitType I2C_InitStructure;
/** I2C periphral configuration */
I2C_DeInit(I2Cx);
I2C_InitStructure.BusMode = I2C_BUSMODE_I2C;
I2C_InitStructure.FmDutyCycle = I2C_FMDUTYCYCLE_2;
I2C_InitStructure.OwnAddr1 = 0xff;
I2C_InitStructure.AckEnable = I2C_ACKEN;
I2C_InitStructure.AddrMode = I2C_ADDR_MODE_7BIT;
I2C_InitStructure.ClkSpeed = I2C_Speed;
I2C_Init(I2Cx, &I2C_InitStructure);
env->initStruct = I2C_InitStructure;
env->I2Cx = I2Cx;
}
tI2cIO I2cPortNation_GetIO(tI2cPortNation *env) {
return (tI2cIO) {
.env = env,
.read = (I2C_IO_Operation) vI2cPortNationRead,
.write = (I2C_IO_Operation) vI2cPortNationWrite,
};
}

27
modular.json Normal file
View File

@ -0,0 +1,27 @@
{
"dep": [
{
"type": "git",
"provider": "NAVIGATOR_UVEOS_NATION_TELIT",
"repo": "I2cPortInterface"
},
{
"type": "git",
"provider": "NAVIGATOR_UVEOS_NATION_TELIT",
"repo": "PeripheralDriver_NATION_N32G45X"
},
{
"type": "git",
"provider": "NAVIGATOR_UVEOS_NATION_TELIT",
"repo": "SystemDelayInterface"
}
],
"cmake": {
"inc_dirs": [
"Inc"
],
"srcs": [
"Src/**.c"
]
}
}