Tool/software:
I'm a beginner with embedded programming and facing problem while connecting two EK-TM4C123GXL boards via I2C to blink the LED. Two boards are connected on I2C0 pins and initialization was done. To confirm the send transection from the master board, code is checking the status of busy bit (while loop code line 98). On debugging, I've found that busy bit never goes to 0 and hence code is stuck in an infinite while loop. Can anyone please help?
Master Code -
#include "TM4C123.h" // Device header #include <stdio.h> void I2C_Init(void); void I2C0_Send(uint8_t slave_addr, char data); void PORTF_Init(void); void delay(void); char I2C0_Recieve(uint8_t slave_addr); #define RCGCI2C (((volatile unsigned long)(0x400FE000+0x620))) #define RCGCGPIO (((volatile unsigned long)(0x400FE000+0x608))) //PB2->SCL AND PB3->SDA #define PORTB_BASE 0x40005000 #define PORTB_AFSEL_R (((volatile unsigned long) (PORTB_BASE + 0x420))) #define PORTB_PCTL_R (((volatile unsigned long) (PORTB_BASE + 0x52C))) #define PORTB_DIR_R (((volatile unsigned long) (PORTB_BASE + 0x400))) #define PORTB_DEN_R (((volatile unsigned long) (PORTB_BASE + 0x51C))) #define PORTB_DATA_R (((volatile unsigned long) (PORTB_BASE + 0x3FC))) #define PORTB_AMSEL_R (((volatile unsigned long) (PORTB_BASE + 0x528))) #define PORTB_ODR_R (((volatile unsigned long) (PORTB_BASE + 0x50C))) #define I2C0_BASE (0x40020000) #define I2C_MSA_R (((volatile unsigned long) (I2C0_BASE + 0x00))) #define I2C_MCS_R_R (((volatile unsigned long) (I2C0_BASE + 0x004))) #define I2C_MCS_W_R (((volatile unsigned long) (I2C0_BASE + 0x004))) #define I2C_MDR_R (((volatile unsigned long) (I2C0_BASE + 0x008))) #define I2C_MTPR_R (((volatile unsigned long) (I2C0_BASE + 0x00C))) #define I2C_MCR_R (((volatile unsigned long) (I2C0_BASE + 0x020))) #define I2C_MBMON_R (((volatile unsigned long) (I2C0_BASE + 0x02C))) //#define I2C_SOAR_R (((volatile unsigned long) (I2C0_BASE + 0x00C))) #define PORTF_BASE 0x40025000 #define PORTF_DIR_R (((volatile unsigned long) (PORTF_BASE + 0x400))) #define PORTF_DEN_R (((volatile unsigned long) (PORTF_BASE + 0x51C))) #define PORTF_DATA_R (((volatile unsigned long) (PORTF_BASE + 0x3FC))) #define PORTF_AFSEL_R (((volatile unsigned long) (PORTF_BASE + 0x420))) #define PORTF_PCTL_R (((volatile unsigned long) (PORTF_BASE + 0x52C))) #define PORTF_AMSEL_R (((volatile unsigned long) (PORTF_BASE + 0x528))) int main(){ char arr[3]={'G','B','G'}; I2C_Init(); PORTF_Init(); uint8_t ad=0x2C; int i=0; while(1){ I2C0_Send(ad,arr[i]); char data=I2C0_Recieve(ad); if (data == 'R') { PORTF_DATA_R = 0x02; // Red LED on PF1 } else if (data == 'G') { PORTF_DATA_R = 0x08; // Green LED on PF3 } else if (data == 'B') { PORTF_DATA_R = 0x04; // Blue LED on PF2 } i =i+1; if(i==3) i=0; delay(); } } void I2C_Init(void){ RCGCI2C|=0x01; RCGCGPIO|=0x02; PORTB_AFSEL_R|=0x0C; PORTB_ODR_R|=0x08;//open drain for data line PORTB_DEN_R|=0x0C; PORTB_PCTL_R|=0x3300; PORTB_AMSEL_R&=~0x0C; I2C_MCR_R=0x10; I2C_MTPR_R=7;//SET CLOCK 100KBPS } void PORTF_Init(void) { RCGCGPIO |= 0x20; // enable GPIO Port F clock PORTF_DIR_R = 0x0E; // PF1, PF2, and PF3 as output (LEDs) PORTF_DEN_R |= 0x0E; // digital enable PF1, PF2, and PF3 PORTF_AFSEL_R &=~0x0E; // disable alternate function PORTF_PCTL_R &=~0xFFF0; // configure as GPIO PORTF_AMSEL_R &= ~0x0E; // disable analog function } void I2C0_Send(uint8_t slave_addr, char data) { while(I2C_MCS_R_R&0x01){};//wait unitt i2c0 is busy I2C_MSA_R = (slave_addr<<1)&0xFE; // Set slave address I2C_MSA_R&=~0x01;//specify a write operation I2C_MDR_R = data&0xFF; I2C_MCS_W_R = 0x07; // Start, Run, and Stop conditions while (I2C_MCS_R_R& 0x01==1) {}; // Wait for the transmission to complete // I2C_MCS_R_R&(0x0D); } char I2C0_Recieve(uint8_t slave_addr){ while(I2C_MCS_R_R&0x01){};//wait unitt i2c0 is busy I2C_MSA_R = (slave_addr<<1)&0xFE; // Set slave address I2C_MSA_R|=0x01;//specify a read operation I2C_MCS_W_R = 0x07; // Start, Run, and Stop conditions while (I2C_MCS_R_R& 0x01) {};//busy bit return (char)I2C_MDR_R & (0xFF); } void delay(void) { unsigned long i = 8000000; while (i > 0) { i--; } }
Slave Code -
#include "TM4C123.h" // Device header #include <stdio.h> void I2C_Init(void); void slave_Send(char data); void PORTF_Init(void); void delay(void); char slave_Recieve(void); #define RCGCI2C (((volatile unsigned long)(0x400FE000+0x620))) #define RCGCGPIO (((volatile unsigned long)(0x400FE000+0x608))) //PB2->SCL AND PB3->SDA #define PORTB_BASE 0x40005000 #define PORTB_AFSEL_R (((volatile unsigned long) (PORTB_BASE + 0x420))) #define PORTB_PCTL_R (((volatile unsigned long) (PORTB_BASE + 0x52C))) #define PORTB_DIR_R (((volatile unsigned long) (PORTB_BASE + 0x400))) #define PORTB_DEN_R (((volatile unsigned long) (PORTB_BASE + 0x51C))) #define PORTB_DATA_R (((volatile unsigned long) (PORTB_BASE + 0x3FC))) #define PORTB_AMSEL_R (((volatile unsigned long) (PORTB_BASE + 0x528))) #define PORTB_ODR_R (((volatile unsigned long) (PORTB_BASE + 0x50C))) #define I2C0_BASE (0x40020000) #define I2C_SOAR_R (((volatile unsigned long) (I2C0_BASE + 0x800))) #define I2C_SCS_R_R (((volatile unsigned long) (I2C0_BASE + 0x804))) #define I2C_SCS_W_R (((volatile unsigned long) (I2C0_BASE + 0x804))) #define I2C_SDR_R (((volatile unsigned long) (I2C0_BASE + 0x808))) #define I2C_MCR_R (((volatile unsigned long) (I2C0_BASE + 0x020))) #define PORTF_BASE 0x40025000 #define PORTF_DIR_R (((volatile unsigned long) (PORTF_BASE + 0x400))) #define PORTF_DEN_R (((volatile unsigned long) (PORTF_BASE + 0x51C))) #define PORTF_DATA_R (((volatile unsigned long) (PORTF_BASE + 0x3FC))) #define PORTF_AFSEL_R (((volatile unsigned long) (PORTF_BASE + 0x420))) #define PORTF_PCTL_R (((volatile unsigned long) (PORTF_BASE + 0x52C))) #define PORTF_AMSEL_R (((volatile unsigned long) (PORTF_BASE + 0x528))) int main(){ char arr[3]={'G','B','R'}; I2C_Init(); PORTF_Init(); int i=0; PORTF_DATA_R=0; while(1){ char data=slave_Recieve(); if (data == 'R') { PORTF_DATA_R = 0x02; // Red LED on PF1 } else if (data == 'G') { PORTF_DATA_R = 0x08; // Green LED on PF3 } else if (data == 'B') { PORTF_DATA_R = 0x04; // Blue LED on PF2 } slave_Send(arr[i]); i =i+1; if(i==3) i=0; } } void I2C_Init(void){ RCGCI2C|=0x01; RCGCGPIO|=0x02; PORTB_AFSEL_R|=0x0C; PORTB_ODR_R|=0x08; PORTB_DEN_R|=0x0C; PORTB_PCTL_R|=0x3300; I2C_MCR_R=0x20;//slave mode is on I2C_SOAR_R=0x2C;//setting its address I2C_SCS_W_R=0x01;//enable slave } void PORTF_Init(void) { RCGCGPIO |= 0x20; // enable GPIO Port F clock PORTF_DIR_R = 0x0E; // PF1, PF2, and PF3 as output (LEDs) PORTF_DEN_R |= 0x0E; // digital enable PF1, PF2, and PF3 PORTF_AFSEL_R &=~0x0E; // disable alternate function PORTF_PCTL_R &=~0xFFF0; // configure as GPIO PORTF_AMSEL_R &= ~0x0E; // disable analog function } void slave_Send( char data) { while(I2C_SCS_R_R&0x02==0){}//wait unittl MASTER IS NOT READY I2C_SDR_R=data; } char slave_Recieve(void){ while(I2C_SCS_R_R&0x01==0){}//wait while data is not sned return (char) I2C_SDR_R&0xFF; } void delay(void) { unsigned long i = 8000000; while (i > 0) { i--; } }