commit 383dbbe13662abab16b32d58391469133935a112 Author: cfif Date: Wed Dec 4 13:10:48 2024 +0300 Init diff --git a/Inc/I2cPortNation.h b/Inc/I2cPortNation.h new file mode 100644 index 0000000..aec1342 --- /dev/null +++ b/Inc/I2cPortNation.h @@ -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 diff --git a/Src/I2cPortNation.c b/Src/I2cPortNation.c new file mode 100644 index 0000000..3c4be30 --- /dev/null +++ b/Src/I2cPortNation.c @@ -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, + }; +} \ No newline at end of file diff --git a/modular.json b/modular.json new file mode 100644 index 0000000..05985f9 --- /dev/null +++ b/modular.json @@ -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" + ] + } +} \ No newline at end of file