Hello Everyone,
I am trying to read data from HMC5883L. I have tried to establish a communication network according to HMC5883L datasheet but I can not read the data. I would appreciate it if you could go through my code and advise me how I could fix the problem. Thanks in advance for your time.
#include "tm4c123gh6pm.h" //Global Variables int i=0; unsigned long DATA; // #define I2C_MCS_ACK 0x00000008 // Data Acknowledge Enable #define I2C_MCS_DATACK 0x00000008 // Acknowledge Data #define I2C_MCS_ADRACK 0x00000004 // Acknowledge Address #define I2C_MCS_STOP 0x00000004 // Generate STOP #define I2C_MCS_START 0x00000002 // Generate START #define I2C_MCS_ERROR 0x00000002 // Error #define I2C_MCS_RUN 0x00000001 // I2C Master Enable #define I2C_MCS_BUSY 0x00000001 // I2C Busy #define I2C_MCR_MFE 0x00000010 // I2C Master Function Enable #define MAXRETRIES 5 // number of receive attempts before giving up void I2C0_Init(void){ SYSCTL_RCGCI2C_R |= 0x0001; // activate I2C0 SYSCTL_RCGCGPIO_R |= 0x0002; // activate port B while((SYSCTL_PRGPIO_R&0x0002) == 0){};// ready? GPIO_PORTB_AFSEL_R |= 0x0C; // 3) enable alt funct on PB2,3 GPIO_PORTB_ODR_R |= 0x08; // 4) enable open drain on PB3 only GPIO_PORTB_DEN_R |= 0x0C; // 5) enable digital I/O on PB2,3 // 6) configure PB2,3 as I2C GPIO_PORTB_PCTL_R = (GPIO_PORTB_PCTL_R&0xFFFF00FF)+0x00003300; GPIO_PORTB_AMSEL_R &= ~0x0C; // 7) disable analog functionality on PB2,3 I2C0_MCR_R = I2C_MCR_MFE; // 9) master function enable I2C0_MTPR_R = 0x07; // 8) configure for 100 kbps clock // 16MHZ*(TPR+1)*20ns => TPR=7 } void Slave_Address (unsigned long slaveAddress){ I2C1_MSA_R= ((slaveAddress) << 1); } void EndTransmission (void){ while(I2C0_MCS_R&I2C_MCS_BUSY){};// wait for I2C ready //I2C0_MSA_R &= ~0x01; // MSA[0] is 0 for send // I2C0_MDR_R = data1&0xFF; // prepare first byte I2C0_MCS_R = (0 // & ~I2C_MCS_ACK // no data ack (no data on send) | I2C_MCS_STOP // generate stop // | I2C_MCS_START // no start/restart | I2C_MCS_RUN); // master enable while(I2C0_MCS_R&I2C_MCS_BUSY){};// wait for transmission done } unsigned long I2C_Send_NO_START ( unsigned long data1){ while(I2C0_MCS_R&I2C_MCS_BUSY){};// wait for I2C ready I2C0_MSA_R &= ~0x01; // MSA[0] is 0 for send I2C0_MDR_R = data1&0xFF; // prepare first byte I2C0_MCS_R = (0 // & ~I2C_MCS_ACK // no data ack (no data on send) // | I2C_MCS_STOP // no stop // | I2C_MCS_START // no start/restart | I2C_MCS_RUN); // master enable while(I2C0_MCS_R&I2C_MCS_BUSY){};// wait for transmission done // return error bits return (I2C0_MCS_R&(I2C_MCS_DATACK|I2C_MCS_ADRACK|I2C_MCS_ERROR)); } unsigned long I2C_Send_NO_STOP ( unsigned long data1){ while(I2C0_MCS_R&I2C_MCS_BUSY){};// wait for I2C ready I2C0_MSA_R &= ~0x01; // MSA[0] is 0 for send I2C0_MDR_R = data1&0xFF; // prepare first byte I2C0_MCS_R = (0 // & ~I2C_MCS_ACK // no data ack (no data on send) // | I2C_MCS_STOP // generate stop | I2C_MCS_START // generate start/restart | I2C_MCS_RUN); // master enable while(I2C0_MCS_R&I2C_MCS_BUSY){};// wait for transmission done // return error bits return (I2C0_MCS_R&(I2C_MCS_DATACK|I2C_MCS_ADRACK|I2C_MCS_ERROR)); } unsigned long I2C_Recv(unsigned long slave){ int retryCounter = 1; do{ while(I2C0_MCS_R&I2C_MCS_BUSY){};// wait for I2C ready I2C0_MSA_R = (slave<<1)&0xFE; // MSA[7:1] is slave address I2C0_MSA_R |= 0x01; // MSA[0] is 1 for receive I2C0_MCS_R = (0 // & ~I2C_MCS_ACK // negative data ack (last byte) | I2C_MCS_STOP // generate stop | I2C_MCS_START // generate start/restart | I2C_MCS_RUN); // master enable while(I2C0_MCS_R&I2C_MCS_BUSY){};// wait for transmission done retryCounter = retryCounter + 1; // increment retry counter } // repeat if error while(((I2C0_MCS_R&(I2C_MCS_ADRACK|I2C_MCS_ERROR)) != 0) && (retryCounter <= MAXRETRIES)); return (I2C0_MDR_R&0xFF); // usually returns 0xFF on error } void SystemInit (void){} int main (void){ I2C0_Init(); Slave_Address (0x1E); // Slave Address is 0x1E according to HMC5883L datasheet //initialization process for “continuous-measurement mode (HMC5883L) Page 18 //(8-average, 15 Hz default, normal measurement) I2C_Send_NO_STOP (0x3C); I2C_Send_NO_START (0x00); I2C_Send_NO_START (0x70); //(Gain=5, or any other desired gain) I2C_Send_NO_STOP (0x3C); I2C_Send_NO_START (0x01); I2C_Send_NO_START (0xA0); //(Continuous-measurement mode) I2C_Send_NO_STOP (0x3C); I2C_Send_NO_START (0x02); I2C_Send_NO_START (0x00); //Delay for ( i =0 ; i< 100000; i++){}; for ( i =0 ; i< 100000; i++){}; // End Transmission EndTransmission (); while (1){ Slave_Address (0x1E); I2C_Send_NO_STOP (0x3D); // I2C Address to Read Data according to HMC5883L datasheet page 2 I2C_Send_NO_START (0x03); // Address location 03 which is X-MSB DATA = I2C_Recv(0x1E); //Reading X-MSB } }