We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hello!! Everyone i am working on LPC1343 Micro-controller and wants to interface RTCC PCF8523 with LPC1343.
I write code for I2C protocol but its not working. The problem is found when i send repeated start from master (LPC1343), the status for this must be 0x10 while i am getting 0x28 every time.
The full code can be downloaded from here:- www.edaboard.com/.../107170d1404924341-pcf8523_rtcc.zip (Its EDABOARD Link Sorry, i dont know how to attach files here.)
The functions used for I2C Protocol are as follow:-
#include "LPC13xx.h" #include "I2C.h" #include "UART.h" void I2C_Init(unsigned char Mode) { LPC_SYSCON->PRESETCTRL |= (1<<1); //De-Asserts Reset Signal to I2C LPC_SYSCON->SYSAHBCLKCTRL |= (1<<5); //Enable I2C Clock LPC_IOCON->PIO0_4 &= ~0x3F; LPC_IOCON->PIO0_4 |= 0x01; //SCL LPC_IOCON->PIO0_5 &= ~0x3F; LPC_IOCON->PIO0_5 |= 0x01; //SDA if(Mode == I2C_SPEED_400) { LPC_I2C->SCLH = 90; //I2PCLK is 72MHz LPC_I2C->SCLL = 90; //I2PCLK is 72MHz } else if(Mode == I2C_SPEED_100) { LPC_I2C->SCLH = 360; //I2PCLK is 72MHz LPC_I2C->SCLL = 360; //I2PCLK is 72MHz } LPC_I2C->CONCLR = 0xFF; //Clear All Flags LPC_I2C->CONSET = (1<<6); //I2C Interface Enable } void I2C_Start(void) { LPC_I2C->CONSET |= 0x20; //Set the Start Bit while(LPC_I2C->STAT!=0x08); //Wait for the Status Bit } void I2C_Restart(void) { LPC_I2C->CONSET |= 0x20; //Set the Start Bit while(LPC_I2C->STAT!=0x10); //Wait for the Status Bit } void I2C_Stop(void) { LPC_I2C->CONSET |= 0x14; //Stop I2C LPC_I2C->CONCLR = 0x08; } void I2C_Write(unsigned char data,unsigned char status) { LPC_I2C->DAT = data; LPC_I2C->CONCLR = 0X28; //Clear Start Flag and SI Interrupt while(LPC_I2C->STAT!=status); //Wait for the Status Byte } unsigned char I2C_Read(void) { LPC_I2C->CONCLR = 0X28; while (LPC_I2C->STAT!=0x50); //Wait for Status Set - 0x50 return(LPC_I2C->DAT); }
In function Read from RTCC (given below)
unsigned char PCF8523_Read(unsigned char Address) { unsigned char temp; I2C_Start(); UART_Write('1'); I2C_Write(PC8523_ADDRESS,0x18); UART_Write('2'); I2C_Write(Address,0x28); UART_Write('3'); I2C_Restart(); UART_Write('4'); I2C_Write(PC8523_ADDRESS+1,0x40); UART_Write('5'); temp = I2C_Read(); UART_Write('6'); I2C_Stop(); UART_Write('7'); return temp; }[/pre> As i dont have debugger i checked the content of Status Bytes on UART, i found that for I2c_Start, the status byte contains 0x08 when sending rtcc address i am getting status = 0x18 and then after sending the address from where i have to read i am getting status = 0x28 which is correct. Upto this point i am getting valid status responses, but after sending Repeated Start i am getting 0x28 each and every time continuously. Can anyone please help me to solve this issue.
The below code has been tested OK with my LPC1343 and DS3231 (My I2C-Slave, I don't have PCF8523). I assume your I2C_Init() is correct.
#include <LPC13xx.h> #define I2C_I2CONSET_AA ((0x04)) #define I2C_I2CONSET_SI ((0x08)) #define I2C_I2CONSET_STO ((0x10)) #define I2C_I2CONSET_STA ((0x20)) #define I2C_I2CONSET_I2EN ((0x40)) #define I2C_I2CONCLR_AAC ((1<<2)) #define I2C_I2CONCLR_SIC ((1<<3)) #define I2C_I2CONCLR_STOC ((1<<4)) #define I2C_I2CONCLR_STAC ((1<<5)) #define I2C_I2CONCLR_I2ENC ((1<<6)) #define I2C_STAT_CODE_BITMASK ((0xF8)) #define I2C_I2STAT_M_TX_START ((0x08)) #define I2C_I2STAT_M_TX_RESTART ((0x10)) #define I2C_I2STAT_M_TX_SLAW_ACK ((0x18)) #define I2C_I2STAT_M_TX_SLAW_NACK ((0x20)) #define I2C_I2STAT_M_TX_DAT_ACK ((0x28)) #define I2C_I2STAT_M_TX_DAT_NACK ((0x30)) #define I2C_I2STAT_M_TX_ARB_LOST ((0x38)) #define I2C_I2STAT_M_RX_START ((0x08)) #define I2C_I2STAT_M_RX_RESTART ((0x10)) #define I2C_I2STAT_M_RX_SLAR_ACK ((0x40)) #define I2C_I2STAT_M_RX_SLAR_NACK ((0x48)) #define I2C_I2STAT_M_RX_DAT_ACK ((0x50)) #define I2C_I2STAT_M_RX_DAT_NACK ((0x58)) #define I2C_I2DAT_BITMASK ((0xFF)) void I2C_Init( LPC_I2C_TypeDef *I2Cx, uint32_t clockrate ); uint32_t I2C_Start(void) { LPC_I2C->CONCLR = I2C_I2CONCLR_AAC | I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC; LPC_I2C->CONSET = I2C_I2CONSET_STA; while (!(LPC_I2C->CONSET & I2C_I2CONSET_SI)); return (LPC_I2C->STAT & I2C_STAT_CODE_BITMASK); } void I2C_Stop(void) { LPC_I2C->CONCLR = I2C_I2CONCLR_AAC | I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC; LPC_I2C->CONSET = I2C_I2CONSET_STO; while (LPC_I2C->CONSET & I2C_I2CONSET_STO); } uint32_t I2C_Write(unsigned char data) { LPC_I2C->DAT = data; LPC_I2C->CONCLR = I2C_I2CONCLR_SIC; while (!(LPC_I2C->CONSET & I2C_I2CONSET_SI)); return (LPC_I2C->STAT & I2C_STAT_CODE_BITMASK); } unsigned char Slave_Read(unsigned char Address) { uint8_t result; if ( I2C_Start() == I2C_I2STAT_M_TX_START ) { LPC_I2C->CONCLR = I2C_I2CONCLR_STAC; if ( I2C_Write(Address) == I2C_I2STAT_M_TX_SLAW_ACK ) { if ( I2C_Start() == I2C_I2STAT_M_TX_RESTART ) { if ( I2C_Write( Address | 0x1 ) == I2C_I2STAT_M_RX_SLAR_ACK ) { LPC_I2C->CONCLR = I2C_I2CONCLR_AAC; LPC_I2C->CONCLR = I2C_I2CONCLR_SIC; while (!(LPC_I2C->CONSET & I2C_I2CONSET_SI)); result = (uint8_t)(LPC_I2C->DAT & I2C_I2DAT_BITMASK); I2C_Stop(); return result; } } } } I2C_Stop(); return 0xE8; } int main(void) { volatile uint8_t result; I2C_Init( LPC_I2C, 100000 ); while(1) { result = Slave_Read(0xD0); /* Check result */ } }
Hello!! The code is working now, i had not cleared the SI Flag when using Repeated Restart Function.
Here is the Updated and Working I2C Functions for LPC1343
#include "LPC13xx.h" #include "I2C.h" void I2C_Init(unsigned char Mode) { LPC_SYSCON->PRESETCTRL |= (1<<1); //De-Asserts Reset Signal to I2C LPC_SYSCON->SYSAHBCLKCTRL |= (1<<5); //Enable I2C Clock LPC_IOCON->PIO0_4 &= ~0x3F; LPC_IOCON->PIO0_4 |= 0x01; //SCL LPC_IOCON->PIO0_5 &= ~0x3F; LPC_IOCON->PIO0_5 |= 0x01; //SDA if(Mode == I2C_SPEED_400) { LPC_I2C->SCLH = 90; //I2PCLK is 72MHz LPC_I2C->SCLL = 90; //I2PCLK is 72MHz } else if(Mode == I2C_SPEED_100) { LPC_I2C->SCLH = 360; //I2PCLK is 72MHz LPC_I2C->SCLL = 360; //I2PCLK is 72MHz } LPC_I2C->CONCLR = 0xFF; //Clear All Flags LPC_I2C->CONSET = (1<<6); //I2C Interface Enable } void I2C_Start(void) { LPC_I2C->CONCLR = 0X28; LPC_I2C->CONSET |= 0x20; //Set the Start Bit while(LPC_I2C->STAT!=0x08); //Wait for the Status Bit } void I2C_Restart(void) { LPC_I2C->CONCLR = 0X28; LPC_I2C->CONSET |= 0x20; //Set the Start Bit while(LPC_I2C->STAT!=0x10); //Wait for the Status Bit } void I2C_Stop(void) { LPC_I2C->CONSET |= 0x14; //Stop I2C LPC_I2C->CONCLR = 0x08; } void I2C_Write(unsigned char data,unsigned char status) { LPC_I2C->CONCLR = 0X28; LPC_I2C->DAT = data; LPC_I2C->CONCLR = 0X28; //Clear Start Flag and SI Interrupt while(LPC_I2C->STAT!=status); //Wait for the Status Byte } unsigned char I2C_Read(void) { LPC_I2C->CONCLR = 0X2C; //Cleat SI and Asset Acknowledgment Flag while(LPC_I2C->STAT!=0x58); return(LPC_I2C->DAT); }