This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Tool/software:
Hi,
I want to create EEPROM library using I2C Protocol without using interrput. It is possible please give an example library.
/*
* I2C.c
*
* Created on: 15-Apr-2024
* Author: Lanware
*/
#include <msp430.h>
#include "I2C.h"
#define MAXPAGEWRITE 32
int PtrTransmit =0 ;
unsigned char I2CBufferArray[66];
unsigned char I2CBuffer;
unsigned int RXByteCtr = 0;
unsigned char ReceiveBuffer[20] = {0};
int ReceiveIndex = 0;
/*----------------------------------------------------------------------------*/
// Description:
// Initialization of the I2C Module
/*----------------------------------------------------------------------------*/
void InitI2C(unsigned char eeprom_i2c_address)
{
P3SEL0 |= BIT2 | BIT6; // I2C pins
P3SEL1 &= ~(BIT2 | BIT6);
// Disable the GPIO power-on default high-impedance mode to activate
// previously configured port settings
PM5CTL0 &= ~LOCKLPM5;
UCB1CTLW0 = UCSWRST; // Enable SW reset
UCB1CTLW0 |= UCMODE_3 | UCMST | UCSSEL__SMCLK | UCSYNC; // I2C master mode, SMCLK
UCB1BRW = 160; // fSCL = SMCLK/160 = ~100kHz
UCB1I2CSA = eeprom_i2c_address; // Slave Address
UCB1CTLW0 &= ~UCSWRST; // Clear SW reset, resume operation
UCB1IE |= UCNACKIE;
}
void I2CWriteInit(void)
{
UCB1I2CSA = 0x50;
UCB1IFG &= ~(UCTXIFG + UCRXIFG);
UCB1IE &= ~UCRXIE; // disable Receive ready interrupt
UCB1IE |= UCTXIE; // enable Transmit ready interrupt
}
/*----------------------------------------------------------------------------*/
// Description:
// Initialization of the I2C Module for Read operation.
/*----------------------------------------------------------------------------*/
void I2CReadInit(void)
{
UCB1CTLW0 &= ~UCTR; // UCTR=0 => Receive Mode (R/W bit = 0)
UCB1I2CSA = 0x50;
UCB1IFG &= ~(UCRXIFG + UCRXIFG);
UCB1IE &= ~UCTXIE; // disable Receive ready interrupt
UCB1IE |= UCRXIE; // enable Transmit ready interrupt
}
void EEPROM_ByteWrite(unsigned int Address, unsigned char *Data)
{
unsigned char adr_hi;
unsigned char adr_lo;
while (UCB1STAT & UCBUSY); // wait until I2C module has
// finished all operations.
adr_hi = Address >> 8; // calculate high byte
adr_lo = Address & 0xFF; // and low byte of address
I2CBufferArray[2] = adr_hi; // Low byte address.
I2CBufferArray[1] = adr_lo; // High byte address.
I2CBufferArray[0] = Data;
PtrTransmit = 2; // set I2CBufferArray Pointer
I2CWriteInit();
UCB1CTLW0 |= UCTR + UCTXSTT; // I2C TX, start condition
__bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupts
while((UCB1CTLW0 & UCTXSTP));
}
void EEPROM_AckPolling(void)
{
while (UCB1STAT & UCBUSY); // wait until I2C module has
// finished all operations
do
{
UCB1STAT = 0x00; // clear I2C interrupt flags
UCB1CTLW0 |= UCTR; // I2CTRX=1 => Transmit Mode (R/W bit = 0)
UCB1CTLW0 &= ~UCTXSTT;
UCB1CTLW0 |= UCTXSTT; // start condition is generated
while(UCB1CTLW0 & UCTXSTT) // wait till I2CSTT bit was cleared
{
if(!(UCNACKIFG & UCB1STAT)) // Break out if ACK received
{
break;
}
}
UCB1CTLW0 |= UCTXSTP; // stop condition is generated after
// slave address was sent => I2C communication is started
while (UCB1CTLW0 & UCTXSTP); // wait till stop bit is reset
__delay_cycles(500); // Software delay
}while(UCNACKIFG & UCB1STAT);
}
unsigned char EEPROM_RandomRead(unsigned int Address)
{
unsigned char adr_hi;
unsigned char adr_lo;
while (UCB1STAT & UCBUSY); // wait until I2C module has
// finished all operations
adr_hi = Address >> 8; // calculate high byte
adr_lo = Address & 0xFF; // and low byte of address
I2CBufferArray[1] = adr_hi; // store single bytes that have to
I2CBufferArray[0] = adr_lo; // be sent in the I2CBuffer.
PtrTransmit = 1; // set I2CBufferArray Pointer
// Write Address first
I2CWriteInit();
UCB1CTLW0 |= UCTR + UCTXSTT; // I2C TX, start condition
// => I2C communication is started
__bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupts
while(UCB1CTLW0 & UCTXSTP); // Ensure stop condition got sent
I2CReadInit();
UCB1CTLW0 |= UCTXSTT; // I2C TX, start condition
while(UCB1CTLW0 & UCTXSTT); // Start condition sent?
UCB1CTLW0 |= UCTXSTP; // I2C stop condition
__bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupts
while(UCB1CTLW0 & UCTXSTP); // Ensure stop condition got sent
return I2CBuffer;
}
void EEPROM_PageWrite(unsigned int StartAddress, unsigned char * Data, unsigned char Size)
{
volatile unsigned int i = 0;
volatile unsigned char counterI2cBuffer;
unsigned char adr_hi;
unsigned char adr_lo;
unsigned int currentAddress = StartAddress;
unsigned char currentSize = Size;
unsigned char bufferPtr = 0;
unsigned char moreDataToRead = 1;
while (UCB1STAT & UCBUSY); // wait until I2C module has
// finished all operations.
// Execute until no more data in Data buffer
while(moreDataToRead)
{
adr_hi = currentAddress >> 8; // calculate high byte
adr_lo = currentAddress & 0xFF; // and low byte of address
// Chop data down to 64-byte packets to be transmitted at a time
// Maintain pointer of current startaddress
if(currentSize > MAXPAGEWRITE)
{
bufferPtr = bufferPtr + MAXPAGEWRITE;
counterI2cBuffer = MAXPAGEWRITE - 1;
PtrTransmit = MAXPAGEWRITE + 1; // set I2CBufferArray Pointer
currentSize = currentSize - MAXPAGEWRITE;
currentAddress = currentAddress + MAXPAGEWRITE;
// Get start address
I2CBufferArray[MAXPAGEWRITE + 1] = adr_hi; // High byte address.
I2CBufferArray[MAXPAGEWRITE] = adr_lo; // Low byte address.
}
else
{
bufferPtr = bufferPtr + currentSize;
counterI2cBuffer = currentSize - 1;
PtrTransmit = currentSize + 1; // set I2CBufferArray Pointer.
moreDataToRead = 0;
currentAddress = currentAddress + currentSize;
// Get start address
I2CBufferArray[currentSize + 1] = adr_hi; // High byte address.
I2CBufferArray[currentSize] = adr_lo; // Low byte address.
}
// Copy data to I2CBufferArray
unsigned char temp;
for(i ; i < bufferPtr ; i++)
{
temp = Data[i]; // Required or else IAR throws a
// warning [Pa082]
I2CBufferArray[counterI2cBuffer] = temp;
counterI2cBuffer--;
}
I2CWriteInit();
UCB1CTLW0 |= UCTR + UCTXSTT; // I2C TX, start condition
__bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupt
while((UCB1CTLW0 & UCTXSTT));
UCB1CTLW0 |= UCTXSTP; // Send stop condition
__delay_cycles( 100000);
EEPROM_AckPolling(); // Ensure data is written in EEPROM
}
}
void EEPROM_SequentialRead(unsigned int Address , unsigned char * Data , unsigned int Size)
{
unsigned char adr_hi;
unsigned char adr_lo;
unsigned int counterSize;
adr_hi = Address >> 8; // calculate high byte
adr_lo = Address & 0xFF; // and low byte of address
I2CBufferArray[1] = adr_hi; // store single bytes that have to
I2CBufferArray[0] = adr_lo; // be sent in the I2CBuffer.
PtrTransmit = 1; // set I2CBufferArray Pointer
// Write Address first
I2CWriteInit();
UCB1CTLW0 |= UCTR + UCTXSTT; // I2C TX, start condition
__bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupts
while(UCB1CTLW0 & UCTXSTP); // Ensure stop condition got sent
// Read Data byte
I2CReadInit();
UCB1CTLW0 |= UCTXSTT; // I2C TX, start condition
while(UCB1CTLW0 & UCTXSTT); // Start condition sent?
for(counterSize = 0 ; counterSize < Size ; counterSize++)
{
__bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupts
Data[counterSize] = I2CBuffer;
}
UCB1CTLW0 |= UCTXSTP; // I2C stop condition
__bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupts
while(UCB1CTLW0 & UCTXSTP); // Ensure stop condition got sent
}
/*---------------------------------------------------------------------------*/
/* Interrupt Service Routines */
/* Note that the Compiler version is checked in the following code and */
/* depending of the Compiler Version the correct Interrupt Service */
/* Routine definition is used. */
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = USCI_B1_VECTOR
__interrupt void USCI_B1_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_B1_VECTOR))) USCI_B1_ISR (void)
#else
#error Compiler not supported!
#endif
{
if(UCTXIFG & UCB1IFG)
{
UCB1TXBUF = I2CBufferArray[PtrTransmit];// Load TX buffer
PtrTransmit--; // Decrement TX byte counter
if(PtrTransmit < 0)
{
while(!(UCB1IFG & UCTXIFG));
UCB1CTLW0 |= UCTXSTP; // I2C stop condition
UCB1IE &= ~UCTXIE; // disable interrupts.
UCB1IFG &= ~UCTXIFG; // Clear USCI_B0 TX int flag
__bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
}
}
else if(UCRXIFG & UCB1IFG)
{
I2CBuffer = UCB1RXBUF; // store received data in buffer
__bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
}
}
Thank you
Athulya Shaji
We just have a SPI interface demo so far https://www.ti.com/lit/ab/slaa769a/slaa769a.pdf
If you do not want to use interrupt you can check the interrupt flag in a while loop to avoid interrupt.
**Attention** This is a public forum