/* * i2c_init.c * * Created on: 5 сент. 2023 г. * Author: seklyuts */ #include "f28x_project.h" #include "i2c_init.h" // // Function to configure I2CA as Master Transmitter. // // // I2C GPIO pins // #define GPIO_PIN_SDAA 0U // GPIO number for I2C SDAA #define GPIO_PIN_SCLA 1U // GPIO number for I2C SCLA #define TIME_OVER 100 //*0.1 mS, 1000 ~ 100 mS, 100 ~ 10mS volatile uint16_t TimerTimeouts = 0, ErrI2c = 0, ErrI2c1 = 0, ErrI2c2 = 0, ErrI2c3 = 0, ErrI2c4 = 0, ErrI2c5 = 0, Addr1[255]; volatile uint16_t RXdata, addrCount=0; void TimerBaseTimeoutInc(void) { if(TimerTimeouts < TIME_OVER*16) TimerTimeouts++; } void I2CMasterGpioInit(void) { // //Configure I2C pins // GPIO_SetupPinMux(GPIO_PIN_SDAA, GPIO_MUX_CPU1, 6); GPIO_SetupPinOptions(GPIO_PIN_SDAA, GPIO_OUTPUT, GPIO_PULLUP); GPIO_SetupPinMux(GPIO_PIN_SCLA, GPIO_MUX_CPU1, 6); GPIO_SetupPinOptions(GPIO_PIN_SCLA, GPIO_OUTPUT, GPIO_PULLUP); } void I2CMasterInit(uint16_t I2C_OwnAddress, uint16_t I2CSlave_Address) { EALLOW; // // Must put I2C into reset before configuring it // I2caRegs.I2CMDR.all &= ~(0x20U); // // I2C configuration. Use a 400kHz I2CCLK with a 50% duty cycle. // //I2C_initMaster(base, DEVICE_SYSCLK_FREQ, 400000, I2C_DUTYCYCLE_50); = 1000000 / (I2CPSC+1) / (I2CCLKL + I2CCLKH) I2caRegs.I2CPSC.all = 49; // Prescaler - need 7-12 Mhz on module clk I2caRegs.I2CCLKL = 12; // NOTE: must be non zero I2caRegs.I2CCLKH = 12; // NOTE: must be non zero // // Configure Master as a Transmitter // I2caRegs.I2CMDR.bit.MST = 0x1; I2caRegs.I2CMDR.bit.TRX = 0x1; // // Set data count // // I2caRegs.I2CCNT = I2C_NUMBYTES; // // Set the bit count to 8 bits per data byte // I2caRegs.I2CMDR.bit.BC = 0x0U; I2caRegs.I2CFFRX.bit.RXFFRST = 1; I2caRegs.I2CFFTX.bit.I2CFFEN = 1; I2caRegs.I2CFFTX.bit.TXFFRST = 1; // // Configure slave and own address // I2caRegs.I2COAR.all = I2C_OwnAddress; // Own address I2caRegs.I2CSAR.all = I2CSlave_Address; // Slave address // // Set emulation mode to FREE // I2caRegs.I2CMDR.bit.FREE = 0x1; // //Clear all status // I2caRegs.I2CSTR.all = 0xFFFF; // // I2C Interrupts // I2caRegs.I2CIER.all = 0x08; // // Take I2C out of reset // I2caRegs.I2CMDR.all |= 0x0020; EDIS; } void I2CWriteRes(void) { I2caRegs.I2CSAR.all = 0xFF; I2caRegs.I2CMDR.bit.MST = 0x1; I2caRegs.I2CMDR.bit.TRX = 0x0; I2caRegs.I2CCNT = 0; I2caRegs.I2CMDR.bit.STT = 0x1; I2caRegs.I2CSTR.bit.BYTESENT = 0x1; I2caRegs.I2CMDR.bit.STP = 0x1; TimerTimeouts = 0; while((I2caRegs.I2CMDR.bit.STP != 0x0)&&(TimerTimeouts < TIME_OVER)); if(TimerTimeouts >= TIME_OVER) ErrI2c1++; I2caRegs.I2CSTR.bit.BYTESENT = 0x1; I2caRegs.I2CMDR.bit.STP = 0x1; I2caRegs.I2CSTR.bit.BYTESENT = 0x1; } uint16_t j = 0; // // Function to send data over I2C. // uint16_t I2CWrite(uint16_t slaveAddr, uint16_t MemAdr, uint16_t byteCount, bool sendStopCondition, uint16_t * I2C_TXdata) { // // Locals // uint16_t index = 0; I2caRegs.I2CFFRX.bit.RXFFRST = 0; I2caRegs.I2CFFTX.bit.I2CFFEN = 0; I2caRegs.I2CFFTX.bit.TXFFRST = 0; I2caRegs.I2CFFRX.bit.RXFFRST = 1; I2caRegs.I2CFFTX.bit.I2CFFEN = 1; I2caRegs.I2CFFTX.bit.TXFFRST = 1; TimerTimeouts = 0; while((I2caRegs.I2CSTR.bit.BB == 1)&&(TimerTimeouts < TIME_OVER)); if(TimerTimeouts >= TIME_OVER) { ErrI2c++; return 1; } // // Configure slave address // I2caRegs.I2CSAR.all = slaveAddr; // Slave address // // Configure I2C as Master Transmitter // I2caRegs.I2CMDR.bit.MST = 0x1; I2caRegs.I2CMDR.bit.TRX = 0x1; // //Set Data Count // I2caRegs.I2CFFTX.bit.TXFFINTCLR = 1; I2caRegs.I2CCNT = byteCount+1; I2caRegs.I2CMDR.bit.NACKMOD = 0x0; I2caRegs.I2CDXR.all = MemAdr ; // //transmit the bytes // for(index=0; index < byteCount; index++) { I2caRegs.I2CDXR.all= I2C_TXdata[index]; } // // send Start condition // I2caRegs.I2CMDR.bit.STT = 0x1; // //wait till byte is sent // TimerTimeouts = 0; while((I2caRegs.I2CFFTX.bit.TXFFST > 0)&&(TimerTimeouts < TIME_OVER*(byteCount+1))); if(TimerTimeouts >= TIME_OVER) { ErrI2c++; return 1; } I2caRegs.I2CFFTX.bit.TXFFINTCLR = 1; TimerTimeouts = 0; while((I2caRegs.I2CSTR.bit.NACK == 0x1)&&(TimerTimeouts < TIME_OVER)); if(TimerTimeouts >= TIME_OVER) { ErrI2c1++; return 1; } if(sendStopCondition) { I2caRegs.I2CMDR.bit.STP = 0x1; TimerTimeouts = 0; while((I2caRegs.I2CMDR.bit.STP != 0x0)&&(TimerTimeouts < TIME_OVER)); if(TimerTimeouts >= TIME_OVER) { ErrI2c2++; return 1; } } I2caRegs.I2CSTR.bit.BYTESENT = 0x1; TimerTimeouts = 0; while(TimerTimeouts < TIME_OVER); return 0; } // // Function to read data over I2C. Returns the number of bytes read // uint16_t ttest=0; uint16_t I2CRead(uint16_t slaveAddr, uint16_t byteCount, bool sendStopCondition, uint16_t * I2C_RXdata) { I2caRegs.I2CMDR.bit.NACKMOD = 0x0; // // Configure slave address // I2caRegs.I2CSAR.all = slaveAddr; // // Configure I2C in Master Receiver mode // I2caRegs.I2CMDR.bit.MST = 0x1; I2caRegs.I2CMDR.bit.TRX = 0x0; uint16_t count = 0; I2caRegs.I2CFFRX.bit.RXFFINTCLR = 0; I2caRegs.I2CCNT = byteCount; I2caRegs.I2CMDR.bit.STT = 0x1; TimerTimeouts = 0; while( (I2caRegs.I2CFFRX.bit.RXFFST < byteCount) && (TimerTimeouts < TIME_OVER*byteCount)); if(TimerTimeouts >= TIME_OVER) { ErrI2c3++; return 1; } I2caRegs.I2CMDR.bit.STP = 0x1; for(count=0; count < byteCount; count++) { RXdata = I2C_RXdata[count] = I2caRegs.I2CDRR.all; } // TimerTimeouts = 0; // while((I2caRegs.I2CSTR.bit.NACK == 0x1)&&(TimerTimeouts < TIME_OVER)); // if(TimerTimeouts >= TIME_OVER) // { // ErrI2c4++; // return 1; // } I2caRegs.I2CMDR.bit.NACKMOD = 0x1; TimerTimeouts = 0; while((I2caRegs.I2CMDR.bit.STP != 0x0)&&(TimerTimeouts < TIME_OVER)); if(TimerTimeouts >= TIME_OVER) { ErrI2c5++; return 1; } I2caRegs.I2CSTR.bit.BYTESENT = 0x1; I2caRegs.I2CFFRX.bit.RXFFINTCLR = 0; return 0; } uint16_t I2CVerify(uint16_t slaveAddr, uint16_t byteCount, bool sendStopCondition, uint16_t * I2C_Vfdata) { uint16_t VerErr = 0; I2caRegs.I2CMDR.bit.NACKMOD = 0x0; // // Configure slave address // I2caRegs.I2CSAR.all = slaveAddr; // // Configure I2C in Master Receiver mode // I2caRegs.I2CMDR.bit.MST = 0x1; I2caRegs.I2CMDR.bit.TRX = 0x0; uint16_t count = 0; I2caRegs.I2CCNT = byteCount; I2caRegs.I2CMDR.bit.STT = 0x1; // // Read the received data into RX buffer // TimerTimeouts = 0; while((count < (byteCount))&&(TimerTimeouts < TIME_OVER)) { // if(count == (byteCount-1)) {I2caRegs.I2CMDR.bit.NACKMOD = 0x1; I2caRegs.I2CMDR.bit.STP = 0x1;} if(I2caRegs.I2CSTR.bit.RRDY ==0x1) { RXdata = I2caRegs.I2CDRR.all; if(I2C_Vfdata[count] != RXdata) VerErr = 1; count++; } } if(TimerTimeouts >= TIME_OVER) {ErrI2c2 += (byteCount - count); return 1;} // // Send STOP condition // if(sendStopCondition) { I2caRegs.I2CMDR.bit.STP = 0x1; TimerTimeouts = 0; while((I2caRegs.I2CMDR.bit.STP != 0x0)&&(TimerTimeouts < TIME_OVER)); I2caRegs.I2CSTR.bit.BYTESENT = 0x1; if(TimerTimeouts >= TIME_OVER) {ErrI2c3++; return 1;} } if(VerErr) return 2; else return 0; }