// // 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, }; }