Twi Problem on xmega128a1

Go To Last Post
3 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have an issue using TWI on Xmega128a1

i would like to integrate HMC5883L magneto

according to the datasheet :

hmc5883l example

 

 

0x3C is the adress to write and 0x3D is to read from the device

 

my question is, in the loop mode, it's written send 0x3D 0x06 

so should it should be like 

 

twiname->MASTER.ADDR = 0x3C; // adress to write
twiname->MASTER.DATA = 0x06;

and than

 

twiname->MASTER.ADDR = 0x3D;

for (....)
{
    data[i]= twiname->MASTER.DATA
}

or should i write 0x06 to the adress to read like

 

twiname->MASTER.ADDR = 0x3C
twiname->MASTER.Data=0x06
for (...)
{
    data[i]=twiname->MASTER.DATA;
}

 

Last Edited: Fri. Oct 23, 2015 - 03:26 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

i tried with this code but when i debug the prog , it's  blocked  in twi_read() function ( it's shown in the code on comment) here :

while(!(twiname->MASTER.STATUS&TWI_MASTER_WIF_bm))

 

 

so why it's not blocked there in the main in write twi_write before entering in while (1) even i used 

while(!(twiname->MASTER.STATUS&TWI_MASTER_WIF_bm))

 

 

also is imortant to notice that this code works some times and the most of the time it's blocked

 

Need some help..

 

 

here is the code :

#include <asf.h>
#define CPU_SPEED 32000000
#define BAUDRATE    400000
#define TWI_BAUD(F_SYS, F_TWI) ((F_SYS / (2 * F_TWI)) - 5)
#define TWI_BAUDSETTING TWI_BAUD(CPU_SPEED, BAUDRATE)

#define HMC_SLAVE_ADDRESS 0x3C; // already shifted !!!!


/******************************************************************/

TWI_t * hmc = &TWIC;

uint8_t twitest[6]={0x00, 0x70, 0x01, 0xA0, 0x02, 0x00}; // bytes to send like shown on the screen shot below
uint8_t bytetoreceive[6];
int16_t raw_x=0;
int16_t raw_y=0;
int16_t raw_z=0;
/****************************************************/

void twi_init(TWI_t * twiname){

	
	twiname->MASTER.CTRLB = TWI_MASTER_SMEN_bm;
	twiname->MASTER.BAUD = TWI_BAUDSETTING;
	twiname->MASTER.CTRLA = TWI_MASTER_ENABLE_bm;
	twiname->MASTER.STATUS = TWI_MASTER_BUSSTATE_IDLE_gc;


	return;
}

/****************************************************/

void twi_write(TWI_t *twiname, uint8_t *writeData){

	uint8_t i;
	
	twiname->MASTER.ADDR = HMC_SLAVE_ADDRESS;  // write to hmc
	
	while(!(twiname->MASTER.STATUS&TWI_MASTER_WIF_bm));
	
	for(i=0;i<6;i++){                
		twiname->MASTER.DATA =writeData[i];
		while(!(twiname->MASTER.STATUS&TWI_MASTER_WIF_bm));
	}


	return;
}

/****************************************************/

void twi_read(TWI_t *twiname, uint8_t *readData){
	// read from RTC
	uint8_t i;
	
	twiname->MASTER.ADDR = HMC_SLAVE_ADDRESS;
	while(!(twiname->MASTER.STATUS&TWI_MASTER_WIF_bm));// ***************** THE PROG IS BLOCKET HERE ********************
	twiname->MASTER.DATA = 0x06;      
	while(!(twiname->MASTER.STATUS&TWI_MASTER_WIF_bm)); // ******* or here ************
	twiname->MASTER.ADDR = 0x3D;    
	
	for(i=0;i<6;i++){                  // read date and time
		while(!(twiname->MASTER.STATUS&TWI_MASTER_RIF_bm));
		readData[i] = twiname->MASTER.DATA;
	
	}


	return;
}

/****************************************************/
void pointer_fix (TWI_t *twiname )
{
	twiname->MASTER.ADDR = HMC_SLAVE_ADDRESS;  // write to RTC
	while(!(twiname->MASTER.STATUS&TWI_MASTER_WIF_bm));
	twiname->MASTER.DATA =0x03;
		while(!(twiname->MASTER.STATUS&TWI_MASTER_WIF_bm));
		delay_ms(67);
}
int main(void){

	twi_init(hmc);
	twi_write(hmc, twitest);
	delay_ms(6);
	while(1){
		
		
		
		twi_read(hmc,bytetoreceive);
		raw_x = ((uint8_t)bytetoreceive[0])<<8;
		raw_x |= bytetoreceive[1];

		raw_z = ((uint8_t)bytetoreceive[2])<<8;
		raw_z |= bytetoreceive[3];

		raw_y = ((uint8_t)bytetoreceive[4])<<8;
		raw_y |= bytetoreceive[5];
	
		pointer_fix(hmc);

		
	}

}

 

 

Thank you

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi, the part where the datasheet says you should send 0x3d and then 0x06 makes no sense (it is a read request, the master is not supposed to send anything after initiating a read request). What they intend to say is send 0x3d and then read 6 bytes. It is actually stated above the section you quoted:

To clock out the new data, send: 0x3D, and clock out DXRA, DXRB, DZRA, DZRB, DYRA, and DYRB located in registers 3 through 8.

/Lars